RSA算法 Android(安卓)JAVA C#互通
16lz
2021-01-26
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 try139 {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 try192 {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 try207 {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 * @return224 */225 public static String encryptDataFromStr(String plainText, PublicKey pubKey)226 {227 228 try229 {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 block237 e.printStackTrace();238 return "";239 }240 }241 242 /**243 * 根据指定私钥对数据进行签名(默认签名算法为"SHA1withRSA")244 * 245 * @param data 要签名的数据246 * @param priKey 私钥247 * @return248 */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 * @return261 */262 public static byte[] signData(byte[] data, PrivateKey priKey, String algorithm)263 {264 try265 {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 * @return284 */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 * @return296 */297 public static boolean verifySign(byte[] data, byte[] sign, PublicKey pubKey,298 String algorithm)299 {300 try301 {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 try340 {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 @Override17 public void onClick(View v)18 {19 // TODO Auto-generated method stub20 21 try22 {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 @Override40 public void onClick(View v)41 {42 43 try44 {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 else108 {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#互通
更多相关文章
- 使用安卓SerialManagerService
- Android(安卓)Studio中如何查看获取MD5和SHA1值(应用签名)
- react-native Android打包APK
- SQLCipher加解密Android(安卓)sqlite
- Base64编码和AES加密
- Android(安卓)微信支付
- Android(安卓)Application Digital Signatures - Android(安卓)
- Android实现信息安全中维吉尼亚密码技术
- Android(安卓)生成 keystore签名文件