2015年3月29日

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

 

posted @ 2015-03-29 14:21 冯岩 阅读(4864) 评论(2) 推荐(2) 编辑

2009年9月18日

jquery.autocomplete.js 插件的自定义搜索规则

摘要: 使jquery.autocomplete增加自定义的查询方法,如有些JSON格式的数组,希望对多个属性进行查询时有用 阅读全文

posted @ 2009-09-18 11:20 冯岩 阅读(15529) 评论(38) 推荐(3) 编辑

2009年7月16日

LINQ TO SQL 动态查询

摘要: 有时候我们的应用程序可能会提供一个用户界面,用户可以使用该用户界面指定一个或多个谓词来筛选数据。这对于刚刚接触LINQ TO SQL的朋友来说可能比较费劲。相对会怀念SQL下的strWhere拼接的方便形式。其实这种情况下LINQ也有比较简单的实现方式。 阅读全文

posted @ 2009-07-16 22:17 冯岩 阅读(4885) 评论(5) 推荐(1) 编辑

2009年7月12日

ASPX多服务器控件下使用Jquery.validate.js

摘要: 解决在ASPX多服务器控件下使用Jquery.validate.js进行数据验证 阅读全文

posted @ 2009-07-12 03:16 冯岩 阅读(3782) 评论(3) 推荐(2) 编辑

2009年5月11日

接受来自服务器的数据连接时发生超时(30000 毫秒)问题原因及解决方法

摘要: 接受来自服务器的数据连接时发生超时(30000 毫秒)问题原因及解决方法 阅读全文

posted @ 2009-05-11 11:28 冯岩 阅读(10542) 评论(0) 推荐(1) 编辑

2009年3月19日

防止网页被客户端IE缓存

摘要: 很多开发人员在维护公司运营的网站项目时,可能经常会遇见一个问题就是,编辑人员又抱怨,首页生成了静态页面,为何我访问内容依然是旧的!也许这时你会向她们解释,这是由于IE为加快访问WEB的速度,缓存了你之前浏览的页面.此时其他人访问应该是新的内容.但人们总是只相信自己的眼睛,相信自己所看到的,所以她们会认为别人访问时也是旧的内容! 阅读全文

posted @ 2009-03-19 10:43 冯岩 阅读(4999) 评论(3) 推荐(1) 编辑

2009年3月18日

dottext阅读之系统调度分析

摘要: 博客园dottext网站调度的实现机制分析 阅读全文

posted @ 2009-03-18 23:59 冯岩 阅读(782) 评论(0) 推荐(0) 编辑

2009年2月16日

Javascript对日期的操作

摘要: Javascript对日期的常用操作 阅读全文

posted @ 2009-02-16 11:29 冯岩 阅读(3612) 评论(1) 推荐(0) 编辑

2009年2月4日

C#读取被进程占用的文件

摘要: 有时候读取的文件已经被系统进程占用,用常规读取方式读取不了。 阅读全文

posted @ 2009-02-04 14:57 冯岩 阅读(11301) 评论(1) 推荐(0) 编辑

2008年12月23日

SqlServer 无日志文件附加

摘要: 给你的SQLSERVER数据库瘦身 阅读全文

posted @ 2008-12-23 23:32 冯岩 阅读(2308) 评论(0) 推荐(0) 编辑

2008年11月26日

windows2003远程桌面退出后系统自动注销的解决方法

摘要: 服务器断开连接后自动注销。运行的程序停止。解决方法! 阅读全文

posted @ 2008-11-26 15:52 冯岩 阅读(23713) 评论(5) 推荐(1) 编辑

2008年10月30日

JS获取触发事件元素的方法

摘要: 记录下 阅读全文

posted @ 2008-10-30 15:57 冯岩 阅读(3233) 评论(0) 推荐(0) 编辑

2008年10月20日

JS处理选取值

摘要: 常用JS处理文档方法 阅读全文

posted @ 2008-10-20 11:42 冯岩 阅读(770) 评论(0) 推荐(0) 编辑

2008年10月7日

Marquee首尾相连不间断移动 开始完全显示

摘要: 有时候需要marquee不间断移动,并且在开始时完全显示,而不是渐渐从右边移动出来,特别是在做图片时需要类似效果! 阅读全文

posted @ 2008-10-07 14:06 冯岩 阅读(12769) 评论(5) 推荐(0) 编辑

2008年9月21日

c#将数据导入Excel另类方法

摘要: C#将数据导出指定模板样式的另类方法 阅读全文

posted @ 2008-09-21 23:04 冯岩 阅读(2326) 评论(1) 推荐(0) 编辑

2008年9月18日

windows Server 2008常见问题及解决方法

摘要: 昨天下载了Windows Server2008,今天先在虚拟机上安装。使用起来的确感觉是速度快!比windows 2000升级到windows 2003变化大多了。应该是一次大的改革!当然使用中也遇见一些问题,有的自己解决,有的在网上找到的方法。在此帖出 阅读全文

posted @ 2008-09-18 22:11 冯岩 阅读(2623) 评论(2) 推荐(0) 编辑

2008年9月17日

.NET 特性Attribute[三]

摘要: 刚刚接触Attribute的朋友可能很难想明白Attribute究竟有何用处,以及在应用程序中我们如何使用Attribute。在这节,通过一个例子来演示Attribute的用处! 阅读全文

posted @ 2008-09-17 22:25 冯岩 阅读(954) 评论(2) 推荐(0) 编辑

2008年9月9日

.NET 特性Attribute[二]

摘要: .NET Framework中对Attribute的支持是一个全新的功能,这种支持来自它的Attribute类。在你的程序中适当地使用这个类,或者是灵活巧妙地利用这个类,将使你的程序获得某种在以往编程中很难做到的能力。本文通过一个例子来说明Attribute的入门级应用! 阅读全文

posted @ 2008-09-09 00:25 冯岩 阅读(956) 评论(1) 推荐(0) 编辑

2008年9月8日

.NET 特性Attribute[一]

摘要: C#允许开发人员以特性(attribute)形式为程序添加说明性的信息。特性可以定义与类,结构体,方法等相关的附加信息(元数据) 阅读全文

posted @ 2008-09-08 23:04 冯岩 阅读(1867) 评论(4) 推荐(0) 编辑

2008年7月29日

[安装程序配置服务器失败]解决SQL Server2000安装失败

摘要: 安装程序配置服务器失败。参考服务器错误日志和C:\windows\sqlstp.log。解决方法 阅读全文

posted @ 2008-07-29 21:17 冯岩 阅读(10900) 评论(0) 推荐(0) 编辑

2008年7月14日

C# 操作 XML 增 删 改 查

摘要: C#操作XML文件!增,删,改,查 阅读全文

posted @ 2008-07-14 23:24 冯岩 阅读(7258) 评论(8) 推荐(0) 编辑

2008年7月8日

C# 与 VB.NET 互转工具 离线版

摘要: 推荐一款转换工具。 正确率还行,翻译的能看懂!免注册! 阅读全文

posted @ 2008-07-08 23:58 冯岩 阅读(843) 评论(0) 推荐(0) 编辑

批量修改文件的编码格式

摘要: 很多时候需要批量修改网站文件夹下文件的编码格式。使用这种方式很简单哈! 阅读全文

posted @ 2008-07-08 23:56 冯岩 阅读(15688) 评论(6) 推荐(2) 编辑

2008年7月4日

分别使用函数及游标实现SQL多行转一列

摘要: 有时候在一些系统中我们需要用SQL语句将一对多关系表中的数据以每条记录一行的形式进行显示。本文分别采用函数及游标的方法来实现该功能。 阅读全文

posted @ 2008-07-04 00:11 冯岩 阅读(3864) 评论(5) 推荐(3) 编辑

2008年6月23日

获取SqlServer2005表结构(字段,主键,外键,递增,描述)

摘要: 在SqlServer2005中获取数据库表结构信息的方法 阅读全文

posted @ 2008-06-23 00:39 冯岩 阅读(22734) 评论(20) 推荐(6) 编辑

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示