RSA加密&解密【Java&Scala】

一.简介

  RSA加密算法是一种非对称加密算法。在公开密钥加密电子商业中RSA被广泛使用。

  RSA公开密钥密码体制。所谓公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

  在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。

  RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。 

二.代码实现【Java版】

  1 package cn.ai;
  2 
  3 import java.io.UnsupportedEncodingException;
  4 import java.security.InvalidKeyException;
  5 import java.security.KeyFactory;
  6 import java.security.KeyPair;
  7 import java.security.KeyPairGenerator;
  8 import java.security.NoSuchAlgorithmException;
  9 import java.security.SecureRandom;
 10 import java.security.interfaces.RSAPrivateKey;
 11 import java.security.interfaces.RSAPublicKey;
 12 import java.security.spec.InvalidKeySpecException;
 13 import java.security.spec.PKCS8EncodedKeySpec;
 14 import java.security.spec.X509EncodedKeySpec;
 15 import java.util.HashMap;
 16 import java.util.Map;
 17 
 18 import javax.crypto.BadPaddingException;
 19 import javax.crypto.Cipher;
 20 import javax.crypto.IllegalBlockSizeException;
 21 import javax.crypto.NoSuchPaddingException;
 22 
 23 import org.apache.commons.codec.binary.Base64;
 24 
 25 public class RSACrypt {
 26 
 27     private static Map<Integer, String> keyMap = new HashMap<Integer, String>();
 28     
 29     /**
 30      * 初始化生成公钥和私钥
 31      * @throws NoSuchAlgorithmException 
 32      */
 33     public static void init() throws NoSuchAlgorithmException{
 34         /**
 35          * KeyPairGenerator用于生成公钥和私钥对,基于RSA算法生成对象
 36          */
 37         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
 38         /**
 39          * 初始化秘钥对生成器,秘钥大小为1024位
 40          */
 41         keyPairGen.initialize(1024, new SecureRandom());
 42         /**
 43          * 生成秘钥
 44          */
 45         KeyPair keyPair = keyPairGen.generateKeyPair();
 46         /**
 47          * 获取私钥
 48          */
 49         RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
 50         String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
 51         /**    
 52          * 获取公钥
 53          */
 54         RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
 55         String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
 56         
 57         /**
 58          * 保存公钥,私钥
 59          */
 60         keyMap.put(0, publicKeyStr); // 公钥
 61         keyMap.put(1, privateKeyStr);// 私钥
 62     }
 63     
 64     /**
 65      * 公钥加密
 66      * @throws NoSuchAlgorithmException 
 67      * @throws InvalidKeySpecException 
 68      * @throws Exception 
 69      */
 70     public static String rsaEncrypt(String content, String publicKey) throws InvalidKeySpecException, NoSuchAlgorithmException, Exception{
 71         //base64编码的公钥
 72         byte[] encoded = Base64.decodeBase64(publicKey);
 73         RSAPublicKey rsaPublicKey = (RSAPublicKey)KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encoded));
 74         // RSA加密
 75         Cipher cipher = Cipher.getInstance("RSA");
 76         cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
 77         
 78         String outPublicKey = Base64.encodeBase64String(cipher.doFinal(content.getBytes("UTF-8")));
 79         
 80         return outPublicKey;
 81     }
 82     
 83     /**
 84      * 私钥解密
 85      * @throws UnsupportedEncodingException 
 86      * @throws NoSuchAlgorithmException 
 87      * @throws InvalidKeySpecException 
 88      * @throws NoSuchPaddingException 
 89      * @throws InvalidKeyException 
 90      * @throws BadPaddingException 
 91      * @throws IllegalBlockSizeException 
 92      * @throws Exception
 93      */
 94     public static String rsaDecrypt(String content, String privateKey) throws UnsupportedEncodingException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
 95         //base64位解码加密后的字符串
 96         byte[] inputByte = Base64.decodeBase64(content.getBytes("UTF-8"));
 97         //base64编码的私钥
 98         byte[] decoded = Base64.decodeBase64(privateKey);
 99         RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
100         //RSA解密
101         Cipher cipher = Cipher.getInstance("RSA");
102         cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
103         String outPrivateKey = new String(cipher.doFinal(inputByte));
104         return outPrivateKey;
105     }
106     
107     public static void main(String[] args) throws Exception {
108         /**
109          * 初始化生成公钥,私钥
110          */
111         init();
112         /**
113          * 加密数据
114          */
115         String message = "abc123";
116         System.out.println("随机生成的公钥为:" + keyMap.get(0));
117         System.out.println("随机生成的私钥为:" + keyMap.get(1));
118 
119         System.out.println("加密前的数据:" + message);
120         String messageEncrypt = rsaEncrypt(message, keyMap.get(0));
121         System.out.println("加密后的数据:" + messageEncrypt);
122         
123         //String mid = "MIIc" + keyMap.get(1).substring(4, keyMap.get(1).length());
124         //System.out.println("随机生成的私钥为:" + mid);
125         String messageDecrypt = rsaDecrypt(messageEncrypt, keyMap.get(1));
126         System.out.println("解密后的数据:" + messageDecrypt);
127     }
128 
129 }

三.结果【Java版】

1 随机生成的公钥为:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzveY+Gdrm4gY2IGT+M1yESXHPLSS7Nq/iex4h2oI3x0kSvYOoepQSPUhZvnUJEsrnYHKI9CZPJXNchqQFdR2Zy70GX/58yA700PVpk278z32aZ4OFkqhrmtULRiwF/ILpjucr7dIrgOU+hFTKHHc0fqhtHVWZVYcf1ZyKP8fQBwIDAQAB
2 随机生成的私钥为:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALO95j4Z2ubiBjYgZP4zXIRJcc8tJLs2r+J7HiHagjfHSRK9g6h6lBI9SFm+dQkSyudgcoj0Jk8lc1yGpAV1HZnLvQZf/nzIDvTQ9WmTbvzPfZpng4WSqGua1QtGLAX8gumO5yvt0iuA5T6EVMocdzR+qG0dVZlVhx/VnIo/x9AHAgMBAAECgYAV9yoRAsXem1aY/MJ60joHLJaM8/5eJqO98L/Q8UwilucWNDTHvRslU3npBb51umczeXTlybh4yaHcd9PJmvNf6LI0LsCAWEqW6Y4/1kX2ro8w/a5uLLZMECa9q0xkn0+QWMMrcHxzUVhlott5lDx9ejiW+a3KpNscQLSxgZSeAQJBAN2N45wUFSvcGFZAOwHL6YpCIrECokdhFFp+eABPYJb+rDFfFyiiK8THk/osD2l0Tqtdl+mPJEAbXU1aK0VdnQECQQDPr9OwC0rpvttzq6TiEJ4S1Dz3kZwS2NkrukbgqWkGpC7HggBjYYyrujoEpEnPvqnm6oTWCDqh+YRWC6RMp4UHAkAJCwiWT0+J6cLoilieOyd+KDLoTLY4+aJuCyl0wcisgRqgLURxuSTWNFs649+BK2kmn3xa4SfWogdN5/dKLocBAkACeZjvNyM8Z97boQcE/qezl73mQWD3xIfKAp1Hnh03TAuWqxDwHkB752s7lO2gQShrLQ5KMqzoMz4FfHwHwdNPAkEAtNG3NONm0f4McwEYyxXkrlLWisf67xkTo6rLfxnf7f+xk8W6u6kf339AZlfOUv5I1BZKfka3hUxaXlpsYmQ0Xg==
3 加密前的数据:abc123
4 加密后的数据:s4P8ihNvDHdqB3libM2lj8eC37TQK/UBrUIKM4If42oMYiCVo/4q07FPLfDYCBMEa9sbdDSFA1mcXiWRvwIH+658Nu+dLSe1SQfuwI+7q0KbP0lQeCh3SkBvTqAt0BmEnpDvSUzn1FH/W8Wlqet9IBsTU7mZioXZ9jCSTvKvU8w=
5 解密后的数据:abc123

四.代码实现【Scala版】

 1 package big.data.analyse.encryption
 2 
 3 import java.security.spec.{PKCS8EncodedKeySpec, X509EncodedKeySpec}
 4 import java.security.{KeyFactory, SecureRandom, KeyPairGenerator}
 5 import javax.crypto.Cipher
 6 
 7 import org.apache.commons.codec.binary.Base64
 8 
 9 /**
10   * Created by zhen on 2019/6/15.
11   */
12 object RSA {
13   var keyMap : Map[Int, String] = Map()
14 
15   /**
16     * 初始化公钥,私钥
17     */
18   def init(): Unit ={
19     val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
20     keyPairGenerator.initialize(1024, new SecureRandom())
21     val keyPair = keyPairGenerator.generateKeyPair()
22     val privateKey = keyPair.getPrivate
23     val privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded))
24 
25     val publicKey = keyPair.getPublic
26     val publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded))
27 
28     keyMap += (0 -> publicKeyStr) // 0表示公钥
29     keyMap += (1 -> privateKeyStr) // 1表示私钥
30   }
31 
32   /**
33     * 公钥加密
34     */
35   def rsaEncrypt(content : String, publicKey : String): String ={
36     val encoded = Base64.decodeBase64(publicKey)
37     val rsaPublicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encoded))
38 
39     val cipher = Cipher.getInstance("RSA")
40     cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey)
41 
42     val enContent = Base64.encodeBase64String(cipher.doFinal(content.getBytes("UTF-8")))
43 
44     return enContent
45   }
46 
47   /**
48     * 私钥解密
49     */
50   def rsaDecrypt(content : String, privateKey : String): String ={
51     val bytes = Base64.decodeBase64(content.getBytes("UTF-8"))
52     val decoded = Base64.decodeBase64(privateKey)
53     val rsaPrivateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded))
54 
55     val cipher = Cipher.getInstance("RSA")
56     cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey)
57 
58     val deContent = new String(cipher.doFinal(bytes))
59 
60     return deContent
61   }
62 
63   /**
64     * 测试
65     * @param args
66     */
67   def main(args: Array[String]) {
68 
69     /**
70       * 初始化加密算法
71       */
72     init()
73     println("公钥:" +keyMap.get(0).get+ "
私钥:" + keyMap.get(1).get)
74 
75     /**
76       * 加密内容
77       */
78     val content = "abc123"
79     println("加密前的数据:" + content)
80 
81     /**
82       * 加密
83       */
84     val enContent = rsaEncrypt(content, keyMap.get(0).get)
85     println("加密后的数据:" + enContent)
86 
87     /**
88       * 解密
89       */
90     val deContent = rsaDecrypt(enContent, keyMap.get(1).get)
91     println("解密后的数据:" + deContent)
92   }
93 }

 五.结果【Scala版】

1 公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpWv6go/JB6/fgkFobB8UNG9yGEPEdJnRxy26YISXb2ACRvC1BZ4bKECdnVk5EMwEyIxtfYLbvf0PjVq1CYAimYd6D97teWSQM0ZsdYYzUeSz+KJABugt4A4LNitnfmn1jOToSdjlXZIlrzKQtNxXi4fEFHqg5CMUgrbU40amrcQIDAQAB
2 私钥:MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKla/qCj8kHr9+CQWhsHxQ0b3IYQ8R0mdHHLbpghJdvYAJG8LUFnhsoQJ2dWTkQzATIjG19gtu9/Q+NWrUJgCKZh3oP3u15ZJAzRmx1hjNR5LP4okAG6C3gDgs2K2d+afWM5OhJ2OVdkiWvMpC03FeLh8QUeqDkIxSCttTjRqatxAgMBAAECgYAOIpgqFET+F5Hi3mmG5AkgZPjs/7EAO9twPAiJDgs45Dh38XrdgKSRbPO8/kkeDBvHcYKxXUMnjjm+WdewOI/AIJfhRD4dSW7vLEhDAD/sWN2gop34uFLIwFI4XESvdlObqFU082HqsiC6qP4b2/W5S5JDSx2kQaRLppl1/wX6mQJBANdhmlp2S3aHalKqdViTyLmwqDmQQQDCrdLUs0BCJIJBaRWiN5EbLeCF4EtbCN8Pe6KtiV1R1ZnAlvm7dVlCldMCQQDJS09ybefxe/CApr6ppK7bwSf2vVOqDO2dBm46oapK6otpSSt1USvah0yGNenu7hoPFFyFe3vlrbV3dQJBFdsrAkEAv67Xxma9ZnHCCGw4H2r3G3vDW+esUlbwiFBQb4HuKBa6xUwnk/bSb532LlqInKyU5gT32Zu5NCsYso1JNPVzjQJBAJNruWKnxW/hAlFmTUq21m0Q+HDHVce7siYHOKFuFubJAZL5SH+iFAj2f//m6k3XSXRzyBLmTeX3I2i6ZA1AsYMCQQCXnuh0VjBTqSrvrEWXlnyiQ1cpQdmAhI6YlnKW3Mcd6jjekCjAG7CXU1N845Ax7btTlF1Ca+vwcaVzm0oF80mQ
3 加密前的数据:abc123
4 加密后的数据:jcSjLubNx/1Vk4FEWBwukb8FK3w/QMNZ6UY5lZxLuMxvQ+sl/9cndIh5wNRkzowxmxDQnNcMlUQ5qwIvKnExSVXfBuoRKBH7J+9q7yb1XQR+m+r53djTrNbV15wztHO7KDh4bhlUSbv217OkTdBMb8Exh4aKuih7cUdsD9XQ+60=
5 解密后的数据:abc123
原文地址:https://www.cnblogs.com/yszd/p/11006039.html