C# RSA和Java RSA互通

来源:互联网 发布:听国学的软件 编辑:程序博客网 时间:2024/05/19 00:51

方法1:

源码:http://download.csdn.net/detail/kith002/4192327#comment

Java中有很好的rsa加密与解密类库,同样这些类库也被迁移到了Androidapi中,但稍有不同,在java中的base64编码和解码apiAndroid稍有不同,Android只是简化了一部分操作。如下就将Android中常用的加密和解密的方法总结如下:
  1.   //设置使用何种加密算法
  2.                 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  3.                 // 密钥位数
  4.                 keyPairGen.initialize(1024);
  5.                 // 密钥对
  6.                 KeyPair keyPair = keyPairGen.generateKeyPair();
  7.                 // 公钥
  8.                 PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  9.                 // 私钥
  10.                 PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
复制代码
以上api需要引入以下的包
  1. import java.security.Key;
  2. import java.security.KeyFactory;
  3. import java.security.KeyPair;
  4. import java.security.KeyPairGenerator;
  5. import java.security.PrivateKey;
  6. import java.security.PublicKey;
  7. import java.security.interfaces.RSAPrivateKey;
  8. import java.security.interfaces.RSAPublicKey;
  9. import java.security.spec.PKCS8EncodedKeySpec;
  10. import java.security.spec.X509EncodedKeySpec;
复制代码
为了公钥跟私钥可以传输和保存,因此可以设置为将他们转化成base64的编码,用到以下方法:
  1. /****************************************
  2.          * 函数说明:getKeyString 根据key得到64位加密字符串
  3.          * 
  4.          * @param key 密钥
  5.          * @throws Exception
  6.          * @return String 加密后的字符串
  7.          * @author 王洪贺 2013-8-21
  8.          ***************************************/
  9.         public static String getKeyString(Key key) throws Exception
  10.         {
  11.                 byte[] keyBytes = key.getEncoded();
  12.                 String s = base64Enc(keyBytes);
  13.                 return s;
  14.         }
复制代码
但加密跟解密的时候需要将base64位的编码转化为key的对象,所以用到以下两个方法:
  1. /****************************************
  2.          * 函数说明:getPublicKey 取得公钥
  3.          * 
  4.          * @param key 公钥字符串
  5.          * @throws Exception
  6.          * @return PublicKey 返回公钥
  7.          * @author 王洪贺 2013-8-21
  8.          ***************************************/
  9.         public static PublicKey getPublicKey(String key) throws Exception
  10.         {
  11.                 byte[] keyBytes;
  12.                 keyBytes = base64Dec(key);

  13.                 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  14.                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  15.                 PublicKey publicKey = keyFactory.generatePublic(keySpec);
  16.                 return publicKey;
  17.         }

  18.         /****************************************
  19.          * 函数说明:getPrivateKey 取得私钥
  20.          * 
  21.          * @param key 私钥字符串
  22.          * @throws Exception
  23.          * @return PrivateKey 返回私钥
  24.          * @author 王洪贺 2013-8-21
  25.          ***************************************/
  26.         public static PrivateKey getPrivateKey(String key) throws Exception
  27.         {
  28.                 byte[] keyBytes;
  29.                 keyBytes = base64Dec(key);

  30.                 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  31.                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  32.                 PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
  33.                 return privateKey;
  34.         }
复制代码
下面就是加密过程,很简单:
  1. // 实例化加解密类
  2.                 Cipher cipher = Cipher.getInstance("RSA");

  3.                 // 明文
  4.                 byte[] plainText = "明文".getBytes();

  5.                 // 加密
  6.                 cipher.init(Cipher.ENCRYPT_MODE, publicKe);
  7.   //将明文转化为根据公钥加密的密文,为byte数组格式
  8.                 byte[] enBytes = cipher.doFinal(plainText);
  9.   //为了方便传输我们可以将byte数组转化为base64的编码
  10.                 String str = base64Enc(enBytes );
复制代码
下面是解密过程,跟加密过程类似:
  1. Cipher cipher = Cipher.getInstance("RSA");
  2. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  3. //先将转为base64编码的加密后的数据转化为byte数组
  4. byte[] enBytes = base64Dec(str);
  5. //解密称为byte数组,应该为字符串数组最后转化为字符串
  6. byte[] deBytes = cipher.doFinal(enBytes);
  7. String strdecoded = new String(deBytes);
复制代码
测试结果如下,能够正常加密和解密 

因为每次生成密钥需要的时间较长,所以密钥经过base64进行编码按照字符串保存了,上面的Android程序中的公钥和私钥转化后的字符串如下:
  1. String strpublicKey =
  2.         "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkh0aKknIsmF838HITg8rdA0I+HwS1huM3FGC/rJC0L0UC/DfNp9tYqNgxAoG4WgG+zNtSz2CxghfM8UaUP8eslQRuJHojuZxgy9MLC37Dm4VQaiXALoYdMU3f2593l61Ads3YHHToA4izYprm5Ng3q83QqJoQsopxysRpN274BwIDAQAB";


  3.         String strprivateKey =
  4.         "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKSHRoqSciyYXzfwchODyt0DQj4fBLWG4zcUYL+skLQvRQL8N82n21io2DECgbhaAb7M21LPYLGCF8zxRpQ/x6yVBG4keiO5nGDL0wsLfsObhVBqJcAuhh0xTd/bn3eXrUB2zdgcdOgDiLNimubk2DerzdComhCyinHKxGk3bvgHAgMBAAECgYAbnNR69z8QOvZoFgOfQNQwKZbZhC0vJhdGLDZclOKoSvKjIJ9g9ZX7mELIXupUfU6jrg/1IvbQc8v4ylmVEes5x0pSzsbhI3iuH7m5PNLXChqzAN4K1uC6qGNy9WL3lDTQJ2LV57/1S7iDLtWCfv/aseOzStUL9Znv19W6lX6YSQJBAOkW9A5niW9X0LxxbcMw+xwqDvfDv2nZWmCLqT56W+rjrUEP62fqRX2KqP+zwtUHOYwvaiQSh35TyQ+m1e+QdbMCQQC0syvPgrg2oMl+MkYy0cE2uMV+vZ6evzSaeq6BosUQsnpe/DOKTQZ5GkB+BnYMFZFF5YwkBifsXdIApb8mC/JdAj91dBuHJqUadiW4z29/7C6dApSIRRsvO1dPTxD5aq7mrdOf9WWp92MM39JJB0wmDH3zJfFWPAAKqC2otWkYTrMCQQCZ2Z8oi9y6LkXAG5/nLu354HHOijXeZV+tU1z25RYyNDO6YbKkQxaKz44vfuLNQSOyRlH+bftZ5Tui73wDMdLFAkEArVdICaxILdndxnPB/KSUFNPIoupBvjz+WhoyuXiujs2KKtojLY5DMa/LkAcW2Akr9ZwqkPVeuDcDbVQrEEyfdg==";
复制代码
根据以上的编码,可以放到其他的平台和语言中去,进行解码后得到对应的公钥和私钥,要发送消息只需要得到公钥即可,要解密消息得到私钥即可。此外,如果两个人互相发消息,需要设置两组不同的公钥和私钥,同一组公钥和私钥不能放在同一个设备中。

base64decode(key)编码是一个自定义的函数,大家完全可以自己写,我就不列出了。以上代码是我研究在java中进行加密与解密的方法,后来测试与c#通信有问题,因为c#的公钥和私钥与java的组成方式不同,需要用函数转换。自己又不太清楚如何转换,后使用一些开源的类,稍加修改,便可以与c#和java服务器互通了。附件中的公钥和私钥是c#中的公钥和私钥,大家也可以通过RSAHelper里的函数转化成自己需要的java的公钥私钥,或者可以用函数自己生成。具体不多讲,我在RSAHelper.java中的api写的很明白,若不明白的请留言。详细代码见附件:

方法2:

C# RSA和Java RSA互通

今天调查了C# RSA和Java RSA,网上很多人说,C#加密或者java加密 ,Java不能解密或者C#不能解密

但是我尝试了一下,发现是可以的,下面就是我尝试的代码,如果您有什么问题,我想看看,他们为什么不能互通? 

<pre name="code" class="html">import java.math.BigInteger;import java.security.KeyFactory;import java.security.PrivateKey;import java.security.PublicKey;import java.security.spec.RSAPrivateKeySpec;import java.security.spec.RSAPublicKeySpec;import javax.crypto.Cipher;public class RSATest { private static String module = "5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=";       private static String exponentString = "AQAB";       private static String delement = "vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=";       private static String encryptString = "Vx/dGjS1YWKRubsoDgiShiwLgqyNE2z/eM65U7HZx+RogwaiZimNBxjuOS6acEhKZx66cMYEAd1fc6oewbEvDIfP44GaN9dCjKE/BkkQlwEg6aTO5q+yqy+nEGe1kvLY9EyXS/Kv1LDh3e/2xAk5FNj8Zp6oU2kq4ewL8kK/ai4=";       /**        * @param args        */       public static void main(String[] args) {           byte[] en = encrypt();           System.out.println(Base64Helper.encode(en));           byte[] enTest = null;                   enTest = Base64Helper.decode(encryptString);                     System.out.println(enTest.length);           System.out.println(en.length);           System.out.println(new String(Dencrypt(en)));           System.out.println(new String(Dencrypt(enTest)));       }         public static byte[] encrypt() {           try {               byte[] modulusBytes = Base64Helper.decode(module);               byte[] exponentBytes = Base64Helper.decode(exponentString);               BigInteger modulus = new BigInteger(1, modulusBytes);               BigInteger exponent = new BigInteger(1, exponentBytes);                 RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);               KeyFactory fact = KeyFactory.getInstance("RSA");               PublicKey pubKey = fact.generatePublic(rsaPubKey);                 Cipher cipher = Cipher.getInstance("RSA");               cipher.init(Cipher.ENCRYPT_MODE, pubKey);                 byte[] cipherData = cipher.doFinal(new String("chenhailong").getBytes());               return cipherData;           } catch (Exception e) {               e.printStackTrace();           }           return null;         }         public static byte[] Dencrypt(byte[] encrypted) {           try {               byte[] expBytes = Base64Helper.decode(delement);               byte[] modBytes = Base64Helper.decode(module);                 BigInteger modules = new BigInteger(1, modBytes);               BigInteger exponent = new BigInteger(1, expBytes);                 KeyFactory factory = KeyFactory.getInstance("RSA");               Cipher cipher = Cipher.getInstance("RSA");                 RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(modules, exponent);               PrivateKey privKey = factory.generatePrivate(privSpec);               cipher.init(Cipher.DECRYPT_MODE, privKey);               byte[] decrypted = cipher.doFinal(encrypted);               return decrypted;           } catch (Exception e) {               e.printStackTrace();           }           return null;       }  }



  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Text;   
  5. using System.Security.Cryptography;   
  6.   
  7. namespace RSA   
  8. {   
  9.     class Program   
  10.     {   
  11.         static void Main(string[] args)   
  12.         {   
  13.             string de  = "iBILuPJFgPMxgpbgN3F2JjD6XjcqRSApjVVbvBBEBDV21Pjj7lTrfhEjSVnJX/MVoZrmX0lxsvoXTMvvVwVF7K7W5hs7Qo+aMN96yWke7wiLEM9M4pPz60A/KSckskiona67tXcqOLXb8N18TKaNCKHv0Ce+GyEKK5+MT7e1vao=";   
  14.             //string encrypt = RSAEncrypt("", "chenhailong");   
  15.             byte[] encrypt = RSAEncrypt("chenhailong");   
  16.             //string name = RSADecrypt(encrypt);   
  17.             string name = RSADecrypt(Convert.FromBase64String(de));   
  18.             Console.WriteLine(encrypt.Length);   
  19.             Console.WriteLine(Convert.ToBase64String(encrypt));   
  20.             Console.WriteLine(name);   
  21.             Console.ReadKey();   
  22.         }   
  23.         /// <summary>   
  24.         /// RSA encrypt   
  25.         /// </summary>   
  26.         /// <param name="publickey"></param>   
  27.         /// <param name="content"></param>   
  28.         /// <returns></returns>   
  29.         public static byte[] RSAEncrypt(string content)   
  30.         {   
  31.             string publickey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";   
  32.             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();   
  33.             byte[] cipherbytes;   
  34.             rsa.FromXmlString(publickey);   
  35.             cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);   
  36.   
  37.             //return Convert.ToBase64String(cipherbytes);   
  38.             return cipherbytes;   
  39.         }   
  40.   
  41.         /// <summary>   
  42.         /// RSA decrypt   
  43.         /// </summary>   
  44.         /// <param name="privatekey"></param>   
  45.         /// <param name="content"></param>   
  46.         /// <returns></returns>   
  47.         public static string RSADecrypt(byte[] content)   
  48.         {   
  49.             string privatekey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>";   
  50.             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();   
  51.             byte[] cipherbytes;   
  52.             rsa.FromXmlString(privatekey);   
  53.             cipherbytes = rsa.Decrypt(content, false);   
  54.   
  55.             return Encoding.UTF8.GetString(cipherbytes);   
  56.         }   
  57.   
  58.   
  59.     }   
  60.   
  61. }  


package com.example.rsatest;import java.io.UnsupportedEncodingException;/** * 自定义Base64转换算法 * @author pengxiangxiang * */public class Base64Helper {    private static char[] base64EncodeChars = new char[]{            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',            'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',            'o', 'p', 'q', 'r', 's', 't', 'u', 'v',            'w', 'x', 'y', 'z', '0', '1', '2', '3',            '4', '5', '6', '7', '8', '9', '+', '/'};    private static byte[] base64DecodeChars = new byte[]{            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,            -1, 0, 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, -1, -1, -1, -1, -1,            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1};       public static String encode(byte[] data) {        StringBuffer sb = new StringBuffer();        int len = data.length;        int i = 0;        int b1, b2, b3;        while (i < len) {            b1 = data[i++] & 0xff;            if (i == len) {                sb.append(base64EncodeChars[b1 >>> 2]);                sb.append(base64EncodeChars[(b1 & 0x3) << 4]);                sb.append("==");                break;            }            b2 = data[i++] & 0xff;            if (i == len) {                sb.append(base64EncodeChars[b1 >>> 2]);                sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);                sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);                sb.append("=");                break;            }            b3 = data[i++] & 0xff;            sb.append(base64EncodeChars[b1 >>> 2]);            sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);            sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);            sb.append(base64EncodeChars[b3 & 0x3f]);        }        return sb.toString();    }       public static byte[] decode(String str){    try {return decodePrivate(str);} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}return new byte[]{};    }        private static byte[] decodePrivate(String str) throws UnsupportedEncodingException{        StringBuffer sb = new StringBuffer();        byte[] data = null;data = str.getBytes("US-ASCII");        int len = data.length;        int i = 0;        int b1, b2, b3, b4;        while (i < len) {                       do {                b1 = base64DecodeChars[data[i++]];            } while (i < len && b1 == -1);            if (b1 == -1) break;                       do {                b2 = base64DecodeChars                        [data[i++]];            } while (i < len && b2 == -1);            if (b2 == -1) break;            sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));                       do {                b3 = data[i++];                if (b3 == 61) return sb.toString().getBytes("iso8859-1");                b3 = base64DecodeChars[b3];            } while (i < len && b3 == -1);            if (b3 == -1) break;            sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));                       do {                b4 = data[i++];                if (b4 == 61) return sb.toString().getBytes("iso8859-1");                b4 = base64DecodeChars[b4];            } while (i < len && b4 == -1);            if (b4 == -1) break;            sb.append((char) (((b3 & 0x03) << 6) | b4));        }        return sb.toString().getBytes("iso8859-1");    }    public static void main(String[] args) throws UnsupportedEncodingException {        String s = "abcd";        System.out.println("加密前:" + s);        String x = encode(s.getBytes());        System.out.println("加密后:" + x);        String x1 = new String(decode(x));        System.out.println("解密后:" + x1);    }} 


有什么问题 请给我留言

下面是Key的互通代码

  1. private byte[] removeMSZero(byte[] data) {   
  2.       byte[] data1;   
  3.       int len = data.length;   
  4.       if (data[0] == 0) {   
  5.           data1 = new byte[data.length - 1];   
  6.           System.arraycopy(data, 1, data1, 0, len - 1);   
  7.       } else  
  8.           data1 = data;   
  9.   
  10.       return data1;   
  11.   }  

1 0