RSA算法属非对称加密算法,在实际使用中,往往客户端使用公钥进行加密传递敏感数据,服务端server使用私钥进行解密,这样防止中间人从网络获取敏感数据的明文。

Android端主要代码如下:

  1 package com.example.rsatest;
  2 
  3 import java.io.UnsupportedEncodingException;
  4 import java.math.BigInteger;
  5 import java.security.KeyFactory;
  6 import java.security.KeyPair;
  7 import java.security.KeyPairGenerator;
  8 import java.security.NoSuchAlgorithmException;
  9 import java.security.PrivateKey;
 10 import java.security.PublicKey;
 11 import java.security.Signature;
 12 import java.security.interfaces.RSAPrivateCrtKey;
 13 import java.security.interfaces.RSAPublicKey;
 14 import java.security.spec.RSAPrivateCrtKeySpec;
 15 import java.security.spec.RSAPublicKeySpec;
 16 import java.util.Date;
 17 
 18 import javax.crypto.Cipher;
 19 
 20 public class RsaHelper
 21 {
 22     /**
 23      * 生成RSA密钥对(默认密钥长度为1024)
 24      * 
 25      * @return
 26      */
 27     public static KeyPair generateRSAKeyPair()
 28     {
 29         return generateRSAKeyPair(1024);
 30     }
 31 
 32     /**
 33      * 生成RSA密钥对
 34      * 
 35      * @param keyLength 密钥长度,范围:512~2048
 36      * @return
 37      */
 38     public static KeyPair generateRSAKeyPair(int keyLength)
 39     {
 40         try
 41         {
 42             KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA/ECB/PKCS1Padding");
 43             kpg.initialize(keyLength);
 44             return kpg.genKeyPair();
 45         }
 46         catch (NoSuchAlgorithmException e)
 47         {
 48             return null;
 49         }
 50     }
 51 
 52     /*
 53      * java端公钥转换成C#公钥
 54      */
 55     public static String encodePublicKeyToXml(PublicKey key)
 56     {
 57         if (!RSAPublicKey.class.isInstance(key))
 58         {
 59             return null;
 60         }
 61         RSAPublicKey pubKey = (RSAPublicKey) key;
 62         StringBuilder sb = new StringBuilder();
 63 
 64         sb.append("<RSAKeyValue>");
 65         sb.append("<Modulus>")
 66             .append(Base64Helper.encode(pubKey.getModulus().toByteArray()))
 67             .append("</Modulus>");
 68         sb.append("<Exponent>")
 69             .append(Base64Helper.encode(pubKey.getPublicExponent().toByteArray()))
 70             .append("</Exponent>");
 71         sb.append("</RSAKeyValue>");
 72         return sb.toString();
 73     }
 74 
 75     /*
 76      * C#端公钥转换成java公钥
 77      */
 78     public static PublicKey decodePublicKeyFromXml(String xml)
 79     {
 80         xml = xml.replaceAll("\r", "").replaceAll("\n", "");
 81         BigInteger modulus =
 82             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
 83                 "<Modulus>", "</Modulus>")));
 84         BigInteger publicExponent =
 85             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
 86                 "<Exponent>", "</Exponent>")));
 87 
 88         RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, publicExponent);
 89 
 90         KeyFactory keyf;
 91         try
 92         {
 93             keyf = KeyFactory.getInstance("RSA");
 94             return keyf.generatePublic(rsaPubKey);
 95         }
 96         catch (Exception e)
 97         {
 98             return null;
 99         }
100     }
101 
102     /*
103      * C#端私钥转换成java私钥
104      */
105     public static PrivateKey decodePrivateKeyFromXml(String xml)
106     {
107         xml = xml.replaceAll("\r", "").replaceAll("\n", "");
108         BigInteger modulus =
109             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
110                 "<Modulus>", "</Modulus>")));
111         BigInteger publicExponent =
112             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
113                 "<Exponent>", "</Exponent>")));
114         BigInteger privateExponent =
115             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml, "<D>",
116                 "</D>")));
117         BigInteger primeP =
118             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml, "<P>",
119                 "</P>")));
120         BigInteger primeQ =
121             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml, "<Q>",
122                 "</Q>")));
123         BigInteger primeExponentP =
124             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
125                 "<DP>", "</DP>")));
126         BigInteger primeExponentQ =
127             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
128                 "<DQ>", "</DQ>")));
129         BigInteger crtCoefficient =
130             new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
131                 "<InverseQ>", "</InverseQ>")));
132 
133         RSAPrivateCrtKeySpec rsaPriKey =
134             new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP,
135                 primeQ, primeExponentP, primeExponentQ, crtCoefficient);
136 
137         KeyFactory keyf;
138         try
139         {
140             keyf = KeyFactory.getInstance("RSA");
141             return keyf.generatePrivate(rsaPriKey);
142         }
143         catch (Exception e)
144         {
145             return null;
146         }
147     }
148 
149     /*
150      * java端私钥转换成C#私钥
151      */
152     public static String encodePrivateKeyToXml(PrivateKey key)
153     {
154         if (!RSAPrivateCrtKey.class.isInstance(key))
155         {
156             return null;
157         }
158         RSAPrivateCrtKey priKey = (RSAPrivateCrtKey) key;
159         StringBuilder sb = new StringBuilder();
160 
161         sb.append("<RSAKeyValue>");
162         sb.append("<Modulus>")
163             .append(Base64Helper.encode(priKey.getModulus().toByteArray()))
164             .append("</Modulus>");
165         sb.append("<Exponent>")
166             .append(Base64Helper.encode(priKey.getPublicExponent().toByteArray()))
167             .append("</Exponent>");
168         sb.append("<P>").append(Base64Helper.encode(priKey.getPrimeP().toByteArray()))
169             .append("</P>");
170         sb.append("<Q>").append(Base64Helper.encode(priKey.getPrimeQ().toByteArray()))
171             .append("</Q>");
172         sb.append("<DP>")
173             .append(Base64Helper.encode(priKey.getPrimeExponentP().toByteArray()))
174             .append("</DP>");
175         sb.append("<DQ>")
176             .append(Base64Helper.encode(priKey.getPrimeExponentQ().toByteArray()))
177             .append("</DQ>");
178         sb.append("<InverseQ>")
179             .append(Base64Helper.encode(priKey.getCrtCoefficient().toByteArray()))
180             .append("</InverseQ>");
181         sb.append("<D>")
182             .append(Base64Helper.encode(priKey.getPrivateExponent().toByteArray()))
183             .append("</D>");
184         sb.append("</RSAKeyValue>");
185         return sb.toString();
186     }
187 
188     // 用公钥加密
189     public static byte[] encryptData(byte[] data, PublicKey pubKey)
190     {
191         try
192         {
193             Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
194             cipher.init(Cipher.ENCRYPT_MODE, pubKey);
195             return cipher.doFinal(data);
196         }
197         catch (Exception e)
198         {
199             return null;
200         }
201     }
202 
203     // 用私钥解密
204     public static byte[] decryptData(byte[] encryptedData, PrivateKey priKey)
205     {
206         try
207         {
208             Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
209             cipher.init(Cipher.DECRYPT_MODE, priKey);
210             return cipher.doFinal(encryptedData);
211         }
212         catch (Exception e)
213         {
214             return null;
215         }
216     }
217 
218     /**
219      * 根据指定公钥进行明文加密
220      * 
221      * @param plainText 要加密的明文数据
222      * @param pubKey 公钥
223      * @return
224      */
225     public static String encryptDataFromStr(String plainText, PublicKey pubKey)
226     {
227 
228         try
229         {
230             byte[] dataByteArray = plainText.getBytes("UTF-8");
231             byte[] encryptedDataByteArray = RsaHelper.encryptData(dataByteArray, pubKey);
232             return Base64Helper.encode(encryptedDataByteArray);
233         }
234         catch (UnsupportedEncodingException e)
235         {
236             // TODO Auto-generated catch block
237             e.printStackTrace();
238             return "";
239         }
240     }
241 
242     /**
243      * 根据指定私钥对数据进行签名(默认签名算法为"SHA1withRSA")
244      * 
245      * @param data 要签名的数据
246      * @param priKey 私钥
247      * @return
248      */
249     public static byte[] signData(byte[] data, PrivateKey priKey)
250     {
251         return signData(data, priKey, "SHA1withRSA");
252     }
253 
254     /**
255      * 根据指定私钥和算法对数据进行签名
256      * 
257      * @param data 要签名的数据
258      * @param priKey 私钥
259      * @param algorithm 签名算法
260      * @return
261      */
262     public static byte[] signData(byte[] data, PrivateKey priKey, String algorithm)
263     {
264         try
265         {
266             Signature signature = Signature.getInstance(algorithm);
267             signature.initSign(priKey);
268             signature.update(data);
269             return signature.sign();
270         }
271         catch (Exception ex)
272         {
273             return null;
274         }
275     }
276 
277     /**
278      * 用指定的公钥进行签名验证(默认签名算法为"SHA1withRSA")
279      * 
280      * @param data 数据
281      * @param sign 签名结果
282      * @param pubKey 公钥
283      * @return
284      */
285     public static boolean verifySign(byte[] data, byte[] sign, PublicKey pubKey)
286     {
287         return verifySign(data, sign, pubKey, "SHA1withRSA");
288     }
289 
290     /**
291      * @param data 数据
292      * @param sign 签名结果
293      * @param pubKey 公钥
294      * @param algorithm 签名算法
295      * @return
296      */
297     public static boolean verifySign(byte[] data, byte[] sign, PublicKey pubKey,
298             String algorithm)
299     {
300         try
301         {
302             Signature signature = Signature.getInstance(algorithm);
303             signature.initVerify(pubKey);
304             signature.update(data);
305             return signature.verify(sign);
306         }
307         catch (Exception ex)
308         {
309             return false;
310         }
311     }
312 
313     public static void main(String[] args)
314     {
315         KeyPair kp = RsaHelper.generateRSAKeyPair();
316         PublicKey pubKey = kp.getPublic();
317         PrivateKey priKey = kp.getPrivate();
318 
319         String pubKeyXml = RsaHelper.encodePublicKeyToXml(pubKey);
320         String priKeyXml = RsaHelper.encodePrivateKeyToXml(priKey);
321         System.out.println("====公钥====");
322         System.out.println(pubKeyXml);
323         System.out.println("====私钥====");
324         System.out.println(priKeyXml);
325 
326         PublicKey pubKey2 = RsaHelper.decodePublicKeyFromXml(pubKeyXml);
327         PrivateKey priKey2 = RsaHelper.decodePrivateKeyFromXml(priKeyXml);
328 
329         System.out.println("====公钥对比====");
330         System.out.println(pubKey.toString());
331         System.out.println("------");
332         System.out.println(pubKey2.toString());
333 
334         System.out.println("====私钥对比====");
335         System.out.println(priKey.toString());
336         System.out.println("------");
337         System.out.println(priKey2.toString());
338 
339         try
340         {
341             String pubKeyXml3 =
342                 "<RSAKeyValue><Modulus>rHESyuI3ny4MLsqDBalW9ySaodCL0e6Bsrl01Q5G1qm2wjUoGULazZSNqZY+JQNjU92tW3Snk5RPIkv+wDj+uOT9LTUjQImltHnzqMvbt06GipVXDOyBLTa7G/zRIe/CrjyJ+XEYX2xIhpe5ayowl3HHUpZ71jRNioyxaVVZ8S0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
343             String priKeyXml3 =
344                 "<RSAKeyValue><Modulus>rHESyuI3ny4MLsqDBalW9ySaodCL0e6Bsrl01Q5G1qm2wjUoGULazZSNqZY+JQNjU92tW3Snk5RPIkv+wDj+uOT9LTUjQImltHnzqMvbt06GipVXDOyBLTa7G/zRIe/CrjyJ+XEYX2xIhpe5ayowl3HHUpZ71jRNioyxaVVZ8S0=</Modulus><Exponent>AQAB</Exponent><P>5a7uM+IeY8QMVQl0q88ZTqWbB555l7+366cUIClTN8z2ZXzTnWFCNoQzUrG14FouJFYumFZD12Ni5MkJK6gqSw==</P><Q>wDMhwwO4kz82uSG+FlCBr06fYk2COTg0TofmSp/5OrVqgkBIe7FgpTpVGzGLk0mvOLcy6UZftq//W0Saow6nZw==</Q><DP>FbjDgliiMyE5YVlxlUYSyKNU1BWivj09caXte1UtL5vMubBiewHVtz4tdGamIr+kmX8lDPcrl1Uo5yY0HdLbnQ==</DP><DQ>kIjjJsgxkWnEOUyKqjU4kSDK8x3ehDEkBLpmEFBlGCU9R14YJAyr5RUM0zpbABQ1VK1P9+UYLUYE/hmFQIHQmQ==</DQ><InverseQ>pxQDThwSnUZ4EaNaCPl1ovYypdQUZaZ/Sld1+0n8FEjkmRcGP1R9VMuj1ViPZg3rvm2GeP8Xv1SJqJUVueWiGA==</InverseQ><D>DxBNoPWEAF7IZ6n/KhZx52MGMw6BuFQKdm9m+lml7Iik03BLUXGapYzNlzvtr9QM8D2UMEIPhX/WLdvPpEEWVzGnD7XpLXjGwfu1ZkJRcXPEZEZ2subh5ZBqOWCFWKv5WwgGYWuYDLHfrBlBgSFWR8cZuyqkmMsWl4CiadXqGA0=</D></RSAKeyValue>";
345 
346             System.out.println((new Date()).toLocaleString() + ": 加载公钥中。。。");
347             PublicKey pubKey3 = RsaHelper.decodePublicKeyFromXml(pubKeyXml3);
348             System.out.println((new Date()).toLocaleString() + ": 加载私钥中。。。");
349             PrivateKey priKey3 = RsaHelper.decodePrivateKeyFromXml(priKeyXml3);
350 
351             String dataStr = "Java与.NET和平共处万岁!";
352             byte[] dataByteArray = dataStr.getBytes("utf-8");
353             System.out.println("data的Base64表示:" + Base64Helper.encode(dataByteArray));
354 
355             System.out.println((new Date()).toLocaleString() + ": 加密中。。。"); // 加密
356             byte[] encryptedDataByteArray = RsaHelper.encryptData(dataByteArray, pubKey3);
357 
358             System.out.println("encryptedData的Base64表示:"
359                 + Base64Helper.encode(encryptedDataByteArray));
360             System.out.println((new Date()).toLocaleString() + ": 解密中。。。"); // 解密
361                                                                             // byte[]
362             byte[] decryptedDataByteArray =
363                 RsaHelper.decryptData(encryptedDataByteArray, priKey3);
364             System.out.println(new String(decryptedDataByteArray, "utf-8"));// 签名
365             System.out.println((new Date()).toLocaleString() + ": 签名中。。。");
366             byte[] signDataByteArray = RsaHelper.signData(dataByteArray, priKey3);
367             System.out.println("signData的Base64表示:"
368                 + Base64Helper.encode(signDataByteArray)); // 验签
369             System.out.println((new Date()).toLocaleString() + ": 验签中。。。");
370             boolean isMatch =
371                 RsaHelper.verifySign(dataByteArray, signDataByteArray, pubKey3);
372             System.out.println("验签结果:" + isMatch);
373 
374         }
375         catch (Exception ex)
376         {
377             ex.printStackTrace();
378         }
379     }
380 }
RsaHelper

相关文章:

  • 2021-08-19
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-09-12
  • 2022-12-23
  • 2022-12-23
  • 2021-12-03
相关资源
相似解决方案