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 }

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

时间: 2024-11-11 10:49:24

RSA算法 Android JAVA C#互通的相关文章

一个基于RSA算法的Java数字签名例子

原文地址:一个基于RSA算法的Java数字签名例子 一.前言: 网络数据安全包括数据的本身的安全性.数据的完整性(防止篡改).数据来源的不可否认性等要素.对数据采用加密算法加密可以保证数据本身的安全性,利用消息摘要可以保证数据的完整性,但是还有一点就是数据来源的不可否认性(也就是数据来自哪里接收者是清楚的,而且发送数据者不可抵赖). 有些方案曾经使用消息认证码(MAC)来保证数据来源于合法的发送着,但是利用消息认证码会带来一个问题,就是通讯双方必须事先约定两者之间的通讯用共享密码.在我们的互联网

RSA算法Java的简单实现

RSA简介 RSA算法据说是目前地球上最重要的加密算法.维基百科是这么介绍的:"对极大整数做因数分解的难度决定了RSA算法的可靠性.换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠.假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降.但找到这样的算法的可能性是非常小的.今天只有短的RSA密钥才可能被暴力破解.到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式.只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的." 看上去很神奇是吧,其实在学习网络

[掌眼]iOS / Android / java / node.js 通用的 AES256 加解密算法

example.m NSString *text = @"text"; NSString *key32 = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding]; NSString *encryptedData = [[data AES256EncryptWithKey:key32] base64EncodedStringWi

AES算法,DES算法,RSA算法JAVA实现

1     AES算法 1.1    算法描述 1.1.1      设计思想 Rijndael密码的设计力求满足以下3条标准: ① 抵抗所有已知的攻击. ② 在多个平台上速度快,编码紧凑. ③ 设计简单. 当前的大多数分组密码,其轮函数是Feistel结构. Rijndael没有这种结构. Rijndael轮函数是由3个不同的可逆均匀变换 1.1.2      密码说明 严格地说,AES和Rijndael加密法并不完全一样(虽然在实际应用中二者可以互换),因为Rijndael加密法可以支持更大

ios下使用RSA算法加密与java后台解密配合demo

首先了解一下几个相关概念,以方便后面遇到的问题的解决: 原网址:http://blog.csdn.net/jinglijun/article/details/7770315RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字.算法基于一个数论:将两个大素数相乘非常容易,但要对这个乘积的结果进行因式分解却非常困难,因此可以把乘积公开作为公钥.该算法能够抵抗目前已知的所有密码攻击.RSA算法是一种非对称算法,算法需要一对密钥

重复造轮子之RSA算法(一) 大素数生成

出于无聊, 打算从头实现一遍RSA算法 第一步, 大素数生成 Java的BigInteger里, 有个现成的方法 public static BigInteger probablePrime(int bitLength, Random rnd) { bitLength是期望生成的素数的二进制位数, rnd是随机数发生器 函数注释表明, 这个方法的返回值为合数的概率为2^-100 生成100个1024位的素数, 耗时13471ms 但是显然我不打算直接使用这个函数, 要做就从最底层做起! 目前的做

RSA加密算法的java实现

package rsa; import java.security.*; import java.security.interfaces.*; import javax.crypto.*; public class Test { public static void main(String[] args){ try{ String message = "广东省广州市越秀区"; Test p = new Test(); System.out.println("明文是"

RSA算法实现传输数据的签名

在不同服务器或系统之间进行交互时我们往往需要进行身份的认证,以满足安全上的防抵赖和防篡改. 要实现以上要求使用非对称加密算法是目前最理想的方案. 以下是具体的实现: 1. 生成RSA算法私钥和公钥对,用openssl(openssl的安装网上有很多资料,可以自行查看) 生成RSA私钥 openssl>genrsa -out rsa_private_key.pem 1024 生成RSA公钥 openssl>rsa -in rsa_private_key.pem -pubout -out rsa_

【转】基于RSA算法实现软件注册码原理初讨

1 前言 目前,商用软件和共享软件绝大部份都是采用注册码授权的方式来保证软件本身不被盗用,以保证自身的利益.尽管很多常用的许多软件系统的某些版本已经被别人破解,但对于软件特殊行业而言,注册码授权的方式还是一种保护软件系统本身的一种有效的手段. 通常而言,注册码授权方式有以下几种方式: u  安装序列号方式:这是最为常用的方式,Mircosoft提供的产品(例如:Windows系列产品.Office系列产品等等)都是采用这种方式.通过一种复杂的算法生成安装序列号,在安装过程中,安装程序对用户输入的