RSA算法 Android JAVA C#互通

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 }

复制代码

 

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;       
        }  
    }   

复制代码

 

 

服务器 端 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 }

复制代码

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#互通

 

原文地址:https://www.cnblogs.com/eflylab/p/4375668.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值