美文网首页
非对称加密解密RSA的实现例子

非对称加密解密RSA的实现例子

作者: 西5d | 来源:发表于2020-09-09 11:41 被阅读0次

    背景

    最近有接触到加密相关的内容,本期以非对称加密为例子,做个简单的总结和记录。首先了解下非对称加密,简单来说非对称指的是加密和解密用不同的秘钥,典型的RSA,这个算法名称是基于三个发明人的名字首字母取的;而对称加密必须要在加解密使用相同的秘钥,典型的AES。这里细节不多展开阐述,涉及到很多数学原理,如大数的质因数分解等,感兴趣的可以找找李永乐等网上比较优秀的科普。这篇文章只是java原生实现的加解密例子。至于其他的如md5,hash等,如果从主观可读的角度来说,也可以称为加密。

    描述

    如下的示例是使用Java原生实现RSA的加密解密,包括用公钥加密,然后私钥解密;或者使用私钥加密,然后公钥解密。注意不同key大小,限制的解密内容大小也不一样,感兴趣的同学可以试试修改key大小和加密内容长度来试试。还有要注意的是RSA加密有一定的性能损耗。

    代码

    import lombok.Data;
    import org.junit.Test;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.RSAPrivateKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    
    @Data
    public class CipherTest {
    
        public static RSAPublicKey rsaPublicKey;
        public static RSAPrivateKey rsaPrivateKey;
    
        static {
            try {
                KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
                keyPairGenerator.initialize(2048);
                KeyPair keyPair = keyPairGenerator.generateKeyPair();
                rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
                rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
    
                System.out.println("pub:" + Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()));
                System.out.println("pri:" + Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
    
        //加密数据
        String text = "abcdefghijklmn";
    
        //公钥加密私钥解密
        @Test
        public void securityByPub() {
            String s = encodeByPub(text);
            System.out.println(s);
            System.out.println(decodeByPri(s));
        }
    
        //私钥加密公钥解密
        @Test
        public void securityByPri() {
            String s = encodeByPri(text);
            System.out.println(s);
            System.out.println(decodeByPub(s));
        }
    
        //公钥加密
        private String encodeByPub(String text) {
            try {
                X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                byte[] res = cipher.doFinal(text.getBytes());
                return Base64.getEncoder().encodeToString(res);
            } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //私钥加密
        private String encodeByPri(String text) {
            try {
                RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent());
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PrivateKey privateKey = keyFactory.generatePrivate(rsaPrivateKeySpec);
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                byte[] res = cipher.doFinal(text.getBytes());
                return Base64.getEncoder().encodeToString(res);
            } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //私钥解密
        private String decodeByPri(String encrypt) {
            try {
                byte[] data = Base64.getDecoder().decode(encrypt);
                PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                byte[] res = cipher.doFinal(data);
                return new String(res);
            } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //公钥解密
        private String decodeByPub(String encrypt) {
            try {
                byte[] data = Base64.getDecoder().decode(encrypt);
                X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, publicKey);
                byte[] res = cipher.doFinal(data);
                return new String(res);
            } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    

    总结

    想了解原理相关的内容可以看如下的参考内容。
    [1]. RSA原理

    相关文章

      网友评论

          本文标题:非对称加密解密RSA的实现例子

          本文链接:https://www.haomeiwen.com/subject/hgleektx.html