Java中使用RSA算法加密

Posted 昂迪梵德

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中使用RSA算法加密相关的知识,希望对你有一定的参考价值。

Java中使用RSA算法加密

概述

RSA加密算法是一种非对称加密算法

RSA加密的方式

  • 使用公钥加密的数据,利用私钥进行解密

  • 使用私钥加密的数据,利用公钥进行解密

    RSA是一对密钥。分别是公钥私钥,这个公钥和私钥其实就是一组数字!其二进制位长度可以是1024位或者2048位.长度越长其加密强度越大,目前为止公之于众的能破解的最大长度为768位密钥,只要高于768位,相对就比较安全.

RSA加密的缺点

由于RSA算法的原理都是大数计算,使得RSA最快的情况也比对称加密算法慢上好几倍。

public class RSAUtils {

    public static String RSA_ALGORITHM = "RSA";
    public static String UTF8 = "UTF-8";

    /**
     * 密钥长度,DSA算法的默认密钥长度是1024
     * 密钥长度必须是64的倍数,在512到65536位之间
     * */
    private static final int KEY_SIZE=1024;

    public static void main(String[] args) throws Exception {
        String password = "1234abcd5678";
        KeyStore keys = createKeys();
        byte[] publicKey = getPublicKey(keys);
        byte[] privateKey = getPrivateKey(keys);
        System.out.println("公钥:"+Base64.encode(publicKey));
        System.out.println("私钥:"+ Base64.encode(privateKey));

        byte[] encryptByPublicKey = encryptByPublicKey(password.getBytes(), publicKey);
        System.out.println("使用公钥加密后的数据:"+Base64.encode(encryptByPublicKey));

        byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey, privateKey);
        System.out.println("使用私钥解密后的数据:"+new String(decryptByPrivateKey));

    }

    /**
     * 生成密钥对
     * @return 密钥对对象
     * @throws NoSuchAlgorithmException
     */
    public static KeyStore createKeys() throws NoSuchAlgorithmException {
        //KeyPairGenerator用于生成公钥和私钥对。密钥对生成器是使用 getInstance 工厂方法
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        keyPairGenerator.initialize(KEY_SIZE);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        KeyStore keyStore = new KeyStore( publicKey, privateKey);
        return keyStore;
    }

    /**
     * 获取私钥
     * @param keyStore
     * @return
     */
    private static byte[] getPrivateKey(KeyStore keyStore){
        return ((RSAPrivateKey)keyStore.privateKey).getEncoded();
    }

    /**
     * 获取公钥
     * @param keyStore
     * @return
     */
    private static byte[] getPublicKey(KeyStore keyStore){
        return ((RSAPublicKey)keyStore.publicKey).getEncoded();
    }

    /**
     * 私钥加密
     * @param data 待加密数据
     * @param key 密钥
     * @return byte[] 加密数据
     * */
    public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{

        //取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory=KeyFactory.getInstance(RSA_ALGORITHM);
        //生成私钥
        PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);
        //数据加密
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥加密
     * @param data
     * @param key
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws NoSuchPaddingException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws InvalidKeyException
     */
    private static byte[] encryptByPublicKey(byte[] data, byte[] key) throws NoSuchAlgorithmException,
            InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        //初始化公钥,根据给定的编码密钥创建一个新的 X509EncodedKeySpec。
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        //数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE,publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 私钥解密
     * @param data 待解密数据
     * @param key 密钥
     * @return byte[] 解密数据
     * */
    public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{
        //取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory=KeyFactory.getInstance(RSA_ALGORITHM);
        //生成私钥
        PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);
        //数据解密
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥解密
     * @param data 待解密数据
     * @param key 密钥
     * @return byte[] 解密数据
     * */
    public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{

        //实例化密钥工厂
        KeyFactory keyFactory=KeyFactory.getInstance(RSA_ALGORITHM);
        //初始化公钥
        //密钥材料转换
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);
        //产生公钥
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);
        //数据解密
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }


    //定义密钥类
    @Data
    @AllArgsConstructor
    public static class KeyStore{
        private Object publicKey;
        private Object privateKey;
    }
}

测试结果:

公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdnS/LflJjuj4M9V63SPe3YUx0uFD/oVoPRwG2
p1HXNSp6x+h7ImVAns9Bx5aKKthTH6V70W0TAdreCwS7WyzakvnHu4zWhGX77JM7/dEgdU5LSK8s
I7YLz4bKhCpjBQGXJiKj/3InDPidWzw6w53Ce207HUzrYgR71rM3/OfewwIDAQAB
私钥:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ2dL8t+UmO6Pgz1XrdI97dhTHS4
UP+hWg9HAbanUdc1KnrH6HsiZUCez0HHlooq2FMfpXvRbRMB2t4LBLtbLNqS+ce7jNaEZfvskzv9
0SB1TktIrywjtgvPhsqEKmMFAZcmIqP/cicM+J1bPDrDncJ7bTsdTOtiBHvWszf8597DAgMBAAEC
gYBb6uuQtV6/IkJFtGNEaJ1uqKO5/jPeoO6wsixhpTqpUywu5p7CENET2onsRsWYVlxKPc54Yy5F
Q3OswqhDy2xgL5AFcCboDHCipVojA/6lQsWnvQL1Go/NkAf88YmIMvcNV6TrlBW3TWOr9D6+/LUW
Hjbmr744bE7eRODAV/PVYQJBAOZe0uIm5mXm+eoyE8BT7SVu7XWeQZNtDNvD0a6h4QxQA+fkftVP
9icAfRxZEi3WH8aCtUJJkDdzo3u11XdPQF8CQQCvJjBoQI+5l4dlBfsN3jvLr9H6U1Hx20EF47t/
FbfSEHHJ0LQ6frVyEqQr2MSuL+RhE4ko+PWpB62meFpmKuwdAkEAxI73xDqIrz3K0wZzT9DMMPpa
5dZoAVA0fnawPB6nFIhZLM0LYxpc3p5OIZfmKPHgHtJ7sdlukcG7JdzaDHi0ZQJAe6pqKWHUWQUd
av3zChKsg5+rkaS8yhi163OlEhECjkZgIU/DwT1v3ZA97FuMWzSjestxX8WQpn0uZci6g0KxHQJA
BA1IIAnT7LlLHDWDXAH3B4U60GQZh7BbfF7m3nQvttLeUOc2hpklN3Rr3hpKRDghX5m5iZeiIPri
nPq25FdzAA==
使用公钥加密后的数据:i9YbxGll3KUQNsNF71NtXKCgZhZd7tpJjTIXW1sg3avxOv0tZ84UO9eheWwBTF4ptOW4tjXKxva7
H2cRSkMknaZ0zGI7cGm/TANevR5cdYVdxa7IBIevDRvj+Lnklo8HQg0QgSqLAQeJ1d38lQkcXoXO
i5Qdol2RFTkC7zIPKdc=
使用私钥解密后的数据:1234abcd5678

以上是关于Java中使用RSA算法加密的主要内容,如果未能解决你的问题,请参考以下文章

RSA算法 JS加密 JAVA解密

Java使用RSA加密算法对内容进行加密

RSA算法 JS加密 JAVA解密

求RSA加密解密算法,c++源代码

Java培训 关于RSA加密算法有哪些应用呢?

RSA加密算法介绍及Java工具类