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
Android客户端调用示例:
1 protected void onCreate(Bundle savedInstanceState)
2 {
3 super.onCreate(savedInstanceState);
4 setContentView(R.layout.activity_main);
5
6 btnencode = (Button) findViewById(R.id.btnencode);
7 btndecode = (Button) findViewById(R.id.btndecode);
8 txtinit = (EditText) findViewById(R.id.txtinit);
9 txtencoded = (EditText) findViewById(R.id.txtencoded);
10 txtencoded2 = (EditText) findViewById(R.id.txtencoded2);
11 lbldecoded = (TextView) findViewById(R.id.lbldecoded);
12
13 btnencode.setOnClickListener(new OnClickListener()
14 {
15
16 @Override
17 public void onClick(View v)
18 {
19 // TODO Auto-generated method stub
20
21 try
22 {
23 String strinit = txtinit.getText().toString().trim();
24 String rs = RsaHelper.encryptDataFromStr(strinit, publicKey);
25 txtencoded.setText(rs);
26 Log.e("decoded", rs);//将rs值拿到c#服务器可解密成功
27 }
28 catch (Exception e)
29 {
30 e.printStackTrace();
31 }
32
33 }
34 });
35
36 btndecode.setOnClickListener(new OnClickListener()
37 {
38
39 @Override
40 public void onClick(View v)
41 {
42
43 try
44 {
45 String strtxtencoded = txtencoded2.getText().toString().trim();
46
47 //C#端加密的内容 也可解密
48 //strtxtencoded = "E7lS+MJCDImpS664YmwbFA+OqYlrLzPOw4/Lkg5aUnjZ/ztQkuh+6LtLGLU5T4aLpErVgI1+1tj74fnz1vv4XApK797uvxAiVIY2izZfwIF4M993Bx7Yy7JfciobXowp+eKsxhp4yrLuOZbM1kdNyhfvvOlMZNiLaXLpKyZat6A=";
49
50 String rs = new String(RsaHelper.decryptData(
51 Base64Helper.decode(strtxtencoded), privateKey), "UTF-8");
52 lbldecoded.setText(rs);
53 Log.e("encoded", rs);
54 }
55 catch (Exception e)
56 {
57 e.printStackTrace();
58 }
59
60 }
61 });
62
63 }
JAVA 客户端程序 加密示例:
public class RSAClient {
private static int MAXENCRYPTSIZE = 117;
private static int MAXDECRYPTSIZE = 128;
public static void main(String[] args) {
/*
*
* 以下xml格式由c#服务端生成的公钥
<RSAKeyValue>
<Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
*/
String modulus = "w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=";
String exponent ="AQAB";
PublicKey p =getPublicKey(modulus,exponent);
//使用上述公钥 针对明文123abc进行加密
//step1.将明文转为BASE64格式
try {
String password = encodeBase64("123abc".getBytes());
byte[] by = decodeBase64(password);
String mask = encrypt(by,p);
System.out.println("请将以下密文复制到c#端进行解密");
System.out.println(mask);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String encodeBase64(byte[] input) throws Exception {
Class clazz = Class
.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod = clazz.getMethod("encode", byte[].class);
mainMethod.setAccessible(true);
Object retObj = mainMethod.invoke(null, new Object[] { input });
return (String) retObj;
}
public static byte[] decodeBase64(String input) throws Exception{
Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod= clazz.getMethod("decode", String.class);
mainMethod.setAccessible(true);
Object retObj=mainMethod.invoke(null, input);
return (byte[])retObj;
}
/**
* 返回RSA公钥
* @param modules
* @param exponent
* @return
*/
public static PublicKey getPublicKey(String modulus, String exponent){
try {
byte[] m = decodeBase64(modulus);
byte[] e = decodeBase64(exponent);
BigInteger b1 = new BigInteger(1,m);
BigInteger b2 = new BigInteger(1,e);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String encrypt2(byte[] source, PublicKey publicKey) throws Exception {
}
public static String encrypt(byte[] source, PublicKey publicKey) throws Exception {
String encryptData ="";
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int length = source.length;
int offset = 0;
byte[] cache;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
int i = 0;
while(length - offset > 0){
if(length - offset > MAXENCRYPTSIZE){
cache = cipher.doFinal(source, offset, MAXENCRYPTSIZE);
}else{
cache = cipher.doFinal(source, offset, length - offset);
}
outStream.write(cache, 0, cache.length);
i++;
offset = i * MAXENCRYPTSIZE;
}
return encodeBase64(outStream.toByteArray());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return encryptData;
}
}
JAVA Client
服务器 端 C#代码:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Security.Cryptography;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace RSA_Android_Demo
9 {
10 /// <summary>
11 /// RSA 非对称加解密算法
12 /// </summary>
13 public class RSAHelper
14 {
15 private int MAXENCRYPTSIZE = 117;
16 private int MAXDECRYPTSIZE = 128;
17
18 public string priKeyXml
19 {
20 get;
21 private set;
22 }
23
24 public string pubKeyXml
25 {
26 get;
27 private set;
28 }
29
30
31 private RSAHelper(string privateKey, string publicKey)
32 {
33 this.priKeyXml = privateKey;
34 this.pubKeyXml = publicKey;
35 }
36
37 public static RSAHelper Load(string privateKey = "", string publicKey = "")
38 {
39 if (string.IsNullOrEmpty(privateKey) && string.IsNullOrEmpty(publicKey))
40 {
41 //无key时生成新密钥
42 return Instance;
43 }
44 return new RSAHelper(privateKey, publicKey);
45 }
46
47 /// <summary>
48 /// 随机生成公私钥并返回对象
49 /// </summary>
50 public static RSAHelper Instance
51 {
52 get
53 {
54 RSACryptoServiceProvider provider = new RSACryptoServiceProvider(1024);
55 var publicKeyXml = provider.ToXmlString(false);
56 //publickey:<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
57 var privateKeyXml = provider.ToXmlString(true);
58 //privatekey:<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent><P>6tzaLZmY+hLLAifunWwcdUSfqTUvKOO5bJ8M1Zt34en40tfBaH9zml9gP8cmXaWyfpiZgHlPS9xlkLngudAiJw==</P><Q>1Xw2E1ufXsCM2JZahB6PH9pCgfD4XPjrqxF9xOWVvfbPmVBZByBIHYRs8ifbjIPvSKuaCfVFVStoIcOYrT9I+w==</Q><DP>mS4iPsuHMtM/BND2mEYC6ZkwaTP+5jRgo6+4tzkHH5lyaFHAG1/FDlJWfEJvi3SezmLI+zojtd6xf4s8PvS40Q==</DP><DQ>I91kMEhaM87hWpmXx05i+RTvy2iyMNxYqzqbCHMRfwJxye3npvzTYLIYo23ywl5/2pOJo1ajOTW7nsB/a8uP9Q==</DQ><InverseQ>EtYQvvBViXf7A5bgh+H4xLlBezD0yziBigoP/xcg1mcuI9Kb9rtPq64hQsajDYeNmm0Ibkxz9ihHr8+uWtdi5w==</InverseQ><D>HSivw2RZKvDlv1lSb/gumEqufALcbF7W3SMS3qxAVGvC3z27Ks/jWTCVwWOg3u+LV99KZC+dk1MWbxq/dJhMmBSiHOT6Sg7wvNMmX58zHl7Bhs702henzbr7CkiWrUcy3pVigr4olT9FlkjQkeEu9VfVW4TRGUDUkixTeh9MMC0=</D></RSAKeyValue>
59
60 return new RSAHelper(privateKeyXml, publicKeyXml);
61 }
62 }
63
64
65
66 /// <summary>
67 /// RSA公钥加密
68 /// </summary>
69 /// <param name="content"></param>
70 /// <param name="publicKeyXml">公钥xml串</param>
71 /// <returns></returns>
72 public string Encrypt(string content)
73 {
74 //string publickey = @"<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
75 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
76 byte[] cipherbytes;
77 rsa.FromXmlString(pubKeyXml);
78 cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
79
80 return Convert.ToBase64String(cipherbytes);
81 //return cipherbytes;
82 }
83 /// <summary>
84 /// RSA私钥解密
85 /// </summary>
86 /// <param name="encryptData">经过Base64编码的密文</param>
87 /// <param name="privateKeyXml">私钥xml串</param>
88 /// <returns>RSA解密后的数据</returns>
89 public string Decrypt(string encryptData)
90 {
91 string decryptData = "";
92 try
93 {
94 RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
95 provider.FromXmlString(priKeyXml);
96 byte[] bEncrypt = Convert.FromBase64String(encryptData);
97 int length = bEncrypt.Length;
98 int offset = 0;
99 string cache;
100 int i = 0;
101 while (length - offset > 0)
102 {
103 if (length - offset > MAXDECRYPTSIZE)
104 {
105 cache = Encoding.UTF8.GetString(provider.Decrypt(GetSplit(bEncrypt, offset, MAXDECRYPTSIZE), false));
106 }
107 else
108 {
109 cache = Encoding.UTF8.GetString(provider.Decrypt(GetSplit(bEncrypt, offset, length - offset), false));
110 }
111 decryptData += cache;
112 i++;
113 offset = i * MAXDECRYPTSIZE;
114 }
115 }
116 catch (Exception e)
117 {
118 throw e;
119 }
120 return decryptData;
121 }
122
123 /// <summary>
124 /// 截取字节数组部分字节
125 /// </summary>
126 /// <param name="input"></param>
127 /// <param name="offset">起始偏移位</param>
128 /// <param name="length">截取长度</param>
129 /// <returns></returns>
130 private byte[] GetSplit(byte[] input, int offset, int length)
131 {
132 byte[] output = new byte[length];
133 for (int i = offset; i < offset + length; i++)
134 {
135 output[i - offset] = input[i];
136 }
137 return output;
138 }
139
140 }
141
142 }
RSAHelper
C#调用示例
1 public void TestDecry()
2 {
3 //java端的密文
4 //以下为android端加密后的密文
5 string pwd =
6 "VpEiGrV8BND+30z/5n03eS7UW/0ZF7NgVnCKPp/5IrpGRI/aoDb0iNehTez8Gcnl1C/g0q71UjLVMjywysbdoTBCaLBq/x85Fw31NNvzc5XOW4St01Q3+78JKkX1CCmSbOPpb2lvMb0D8iGiq3gLt3UZZpLLkbyBZDaXP2oHaIc=";
7 //Convert.ToBase64String(bytes);
8
9 //服务端私钥
10 string privateKey = "<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent><P>6tzaLZmY+hLLAifunWwcdUSfqTUvKOO5bJ8M1Zt34en40tfBaH9zml9gP8cmXaWyfpiZgHlPS9xlkLngudAiJw==</P><Q>1Xw2E1ufXsCM2JZahB6PH9pCgfD4XPjrqxF9xOWVvfbPmVBZByBIHYRs8ifbjIPvSKuaCfVFVStoIcOYrT9I+w==</Q><DP>mS4iPsuHMtM/BND2mEYC6ZkwaTP+5jRgo6+4tzkHH5lyaFHAG1/FDlJWfEJvi3SezmLI+zojtd6xf4s8PvS40Q==</DP><DQ>I91kMEhaM87hWpmXx05i+RTvy2iyMNxYqzqbCHMRfwJxye3npvzTYLIYo23ywl5/2pOJo1ajOTW7nsB/a8uP9Q==</DQ><InverseQ>EtYQvvBViXf7A5bgh+H4xLlBezD0yziBigoP/xcg1mcuI9Kb9rtPq64hQsajDYeNmm0Ibkxz9ihHr8+uWtdi5w==</InverseQ><D>HSivw2RZKvDlv1lSb/gumEqufALcbF7W3SMS3qxAVGvC3z27Ks/jWTCVwWOg3u+LV99KZC+dk1MWbxq/dJhMmBSiHOT6Sg7wvNMmX58zHl7Bhs702henzbr7CkiWrUcy3pVigr4olT9FlkjQkeEu9VfVW4TRGUDUkixTeh9MMC0=</D></RSAKeyValue>";
11
12 //解密
13 string userpwd = RSAHelper.Load(privateKey: privateKey).Decrypt(pwd);
14
15
16
17 //C# 端用公钥加密
18 string publickey = @"<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
19
20 var abc = RSAHelper.Load(publicKey: publickey).Encrypt("abc123中文");//查将此生成的值拿到android工程中解密,至此达到RSA 的 C#—Android双方互通
21
22 //C#端也可 解密
23 string userpwd2 = RSAHelper.Load(privateKey: privateKey).Decrypt(abc);
24
25
26 }
可运行的示例代码下载:
RSA算法JAVA公钥加密,C#私钥解密
RSA算法Android C#互通