现在的位置: 首页 > 综合 > 正文

C# Java间进行RSA加密解密交互(二) .

2018年02月12日 ⁄ 综合 ⁄ 共 14789字 ⁄ 字号 评论关闭

接着前面一篇文章C# Java间进行RSA加密解密交互,继续探讨这个问题。

在前面,虽然已经实现了C# Java间进行RSA加密解密交互,但是还是与项目中要求的有所出入。在项目中,客户端(Java)的加密是通过这么一个方法实现的:

  1. /** 
  2.  * RSA加密 
  3.  * @param text--待加密的明文 
  4.  * @param key--公钥,由服务器端提供的经base64编码的字符串 
  5.  * @return 
  6.  */  
  7. public static String RSAEncryptoWithPublicKey(String text, String key) {  
  8.     String result = null;  
  9.     try {  
  10.         byte[] publicKeyByte = base64Decrypto(key);  
  11.   
  12.         X509EncodedKeySpec x509 = new X509EncodedKeySpec(publicKeyByte);  
  13.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  14.         PublicKey publicKey = keyFactory.generatePublic(x509);  
  15.   
  16.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  17.         cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  18.   
  19.         result = base64Encrypto(cipher.doFinal(text.getBytes()));  
  20.     } catch (Exception e) {  
  21.         e.printStackTrace();  
  22.         return null;  
  23.     }  
  24.     return result;  
  25. }  

在上一篇中的实现,需要客户端先做一次解析工作,而已经开发好的客户端是没有这一层的,所以得想个办法,在服务器端(C#)完成这项工作。但是经过多次尝试,依然未果。于是换一种方式,密钥对不由C#提供,而转而有Java提供,生成客户端需要的公钥形式,并解析公钥私钥,组装C# 的XML格式的密钥对字符串。

下面贴一下RSA密钥对生成代码(参考RSA的密钥把JAVA格式转换成C#的格式

  1. import java.io.UnsupportedEncodingException;  
  2. import java.lang.reflect.Method;  
  3. import java.security.KeyFactory;  
  4. import java.security.KeyPair;  
  5. import java.security.KeyPairGenerator;  
  6. import java.security.NoSuchAlgorithmException;  
  7. import java.security.PublicKey;  
  8. import java.security.interfaces.RSAPrivateCrtKey;  
  9. import java.security.interfaces.RSAPrivateKey;  
  10. import java.security.interfaces.RSAPublicKey;  
  11. import java.security.spec.PKCS8EncodedKeySpec;  
  12. import java.security.spec.X509EncodedKeySpec;  
  13. import java.util.HashMap;  
  14.   
  15. /** 
  16.  * @author Administrator 
  17.  *  
  18.  */  
  19. public class RSAJavaToCSharp {  
  20.     public static void main(String[] args) throws Exception {  
  21.         HashMap<String, Object> map = getKeys();  
  22.         RSAPublicKey publicKey = (RSAPublicKey) map.get("PUBLIC");  
  23.         RSAPrivateKey privateKey = (RSAPrivateKey) map.get("PRIVATE");  
  24.           
  25.         String publicKeyString = getRSAPublicKeyAsNetFormat(publicKey.getEncoded());  
  26.         String privateKeyString = getRSAPrivateKeyAsNetFormat(privateKey.getEncoded());  
  27.           
  28.         System.out.println(encodeBase64(publicKey.getEncoded()));//此处为客户端加密时需要的公钥字符串
      
  29.         System.out.println(encodePublicKeyToXml(publicKey));  
  30.         System.out.println(publicKeyString);  
  31.         System.out.println(privateKeyString);  
  32.     }  
  33.   
  34.     /**获取密钥对 
  35.      * @return 
  36.      * @throws NoSuchAlgorithmException 
  37.      */  
  38.     public static HashMap<String, Object> getKeys()  
  39.             throws NoSuchAlgorithmException {  
  40.         HashMap<String, Object> map = new HashMap<String, Object>();  
  41.         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
  42.         keyPairGen.initialize(1024);  
  43.         KeyPair keyPair = keyPairGen.generateKeyPair();  
  44.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
  45.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
  46.         map.put("PUBLIC", publicKey);  
  47.         map.put("PRIVATE", privateKey);  
  48.         return map;  
  49.     }  
  50.   
  51.     /** 
  52.      * 私钥转换成C#格式 
  53.      * @param encodedPrivkey 
  54.      * @return 
  55.      */  
  56.     private static String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivateKey) {  
  57.         try {  
  58.             StringBuffer buff = new StringBuffer(1024);  
  59.   
  60.             PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(  
  61.                     encodedPrivateKey);  
  62.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  63.             RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory  
  64.                     .generatePrivate(pvkKeySpec);  
  65.   
  66.             buff.append("<RSAKeyValue>");  
  67.             buff.append("<Modulus>"  
  68.                     + encodeBase64(removeMSZero(pvkKey.getModulus()  
  69.                             .toByteArray())) + "</Modulus>");  
  70.   
  71.             buff.append("<Exponent>"  
  72.                     + encodeBase64(removeMSZero(pvkKey.getPublicExponent()  
  73.                             .toByteArray())) + "</Exponent>");  
  74.   
  75.             buff.append("<P>"  
  76.                     + encodeBase64(removeMSZero(pvkKey.getPrimeP()  
  77.                             .toByteArray())) + "</P>");  
  78.   
  79.             buff.append("<Q>"  
  80.                     + encodeBase64(removeMSZero(pvkKey.getPrimeQ()  
  81.                             .toByteArray())) + "</Q>");  
  82.   
  83.             buff.append("<DP>"  
  84.                     + encodeBase64(removeMSZero(pvkKey.getPrimeExponentP()  
  85.                             .toByteArray())) + "</DP>");  
  86.   
  87.             buff.append("<DQ>"  
  88.                     + encodeBase64(removeMSZero(pvkKey.getPrimeExponentQ()  
  89.                             .toByteArray())) + "</DQ>");  
  90.   
  91.             buff.append("<InverseQ>"  
  92.                     + encodeBase64(removeMSZero(pvkKey.getCrtCoefficient()  
  93.                             .toByteArray())) + "</InverseQ>");  
  94.   
  95.             buff.append("<D>"  
  96.                     + encodeBase64(removeMSZero(pvkKey.getPrivateExponent()  
  97.                             .toByteArray())) + "</D>");  
  98.             buff.append("</RSAKeyValue>");  
  99.   
  100.             return buff.toString();  
  101.         } catch (Exception e) {  
  102.             System.err.println(e);  
  103.             return null;  
  104.         }  
  105.     }  
  106.   
  107.     /** 
  108.      * 公钥转成C#格式 
  109.      * @param encodedPrivkey 
  110.      * @return 
  111.      */  
  112.     private static String getRSAPublicKeyAsNetFormat(byte[] encodedPublicKey) {  
  113.         try {  
  114.             StringBuffer buff = new StringBuffer(1024);  
  115.               
  116.             //Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
      
  117.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  118.             RSAPublicKey pukKey = (RSAPublicKey) keyFactory  
  119.                     .generatePublic(new X509EncodedKeySpec(encodedPublicKey));  
  120.   
  121.             buff.append("<RSAKeyValue>");  
  122.             buff.append("<Modulus>"  
  123.                     + encodeBase64(removeMSZero(pukKey.getModulus()  
  124.                             .toByteArray())) + "</Modulus>");  
  125.             buff.append("<Exponent>"  
  126.                     + encodeBase64(removeMSZero(pukKey.getPublicExponent()  
  127.                             .toByteArray())) + "</Exponent>");  
  128.             buff.append("</RSAKeyValue>");  
  129.             return buff.toString();  
  130.         } catch (Exception e) {  
  131.             System.err.println(e);  
  132.             return null;  
  133.         }  
  134.     }  
  135.   
  136.     /** 
  137.      * 公钥转换成C#格式 
  138.      * @param key 
  139.      * @return 
  140.      * @throws Exception 
  141.      */  
  142.     public static String encodePublicKeyToXml(PublicKey key) throws Exception {  
  143.         if (!RSAPublicKey.class.isInstance(key)) {  
  144.             return null;  
  145.         }  
  146.         RSAPublicKey pubKey = (RSAPublicKey) key;  
  147.         StringBuilder sb = new StringBuilder();  
  148.   
  149.         sb.append("<RSAKeyValue>");  
  150.         sb.append("<Modulus>")  
  151.                 .append(encodeBase64(removeMSZero(pubKey.getModulus()  
  152.                         .toByteArray()))).append("</Modulus>");  
  153.         sb.append("<Exponent>")  
  154.                 .append(encodeBase64(removeMSZero(pubKey.getPublicExponent()  
  155.                         .toByteArray()))).append("</Exponent>");  
  156.         sb.append("</RSAKeyValue>");  
  157.         return sb.toString();  
  158.     }  
  159.   
  160.     /** 
  161.      * @param data 
  162.      * @return 
  163.      */  
  164.     private static byte[] removeMSZero(byte[] data) {  
  165.         byte[] data1;  
  166.         int len = data.length;  
  167.         if (data[0] == 0) {  
  168.             data1 = new byte[data.length - 1];  
  169.             System.arraycopy(data, 1, data1, 0, len - 1);  
  170.         } else  
  171.             data1 = data;  
  172.   
  173.         return data1;  
  174.     }  
  175.   
  176.     /** 
  177.      * base64编码 
  178.      * @param input 
  179.      * @return 
  180.      * @throws Exception 
  181.      */  
  182.     public static String encodeBase64(byte[] input) throws Exception {  
  183.         Class clazz = Class  
  184.                 .forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");  
  185.         Method mainMethod = clazz.getMethod("encode"byte[].class);  
  186.         mainMethod.setAccessible(true);  
  187.         Object retObj = mainMethod.invoke(nullnew Object[] { input });  
  188.         return (String) retObj;  
  189.     }  
  190.   
  191.     /** 
  192.      * base64解码  
  193.      * @param input 
  194.      * @return 
  195.      * @throws Exception 
  196.      */  
  197.     public static byte[] decodeBase64(String input) throws Exception {  
  198.         Class clazz = Class  
  199.                 .forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");  
  200.         Method mainMethod = clazz.getMethod("decode", String.class);  
  201.         mainMethod.setAccessible(true);  
  202.         Object retObj = mainMethod.invoke(null, input);  
  203.         return (byte[]) retObj;  
  204.     }  
  205.   
  206.     public static String byteToString(byte[] b)  
  207.             throws UnsupportedEncodingException {  
  208.         return new String(b, "utf-8");  
  209.     }  
  210. }  

为了方便在服务器端使用,初始想法是想将java文件封装为.dll文件,共C#调用,测试后,发现这样做行不通,bug提示类找不到,这是因为java代码中还导入了其他jar包的缘故。

于是,退而求其次,将上述java文件Export为可执行的jar文件,并将生成的密钥对写入相应文件中。再由C#读取,提供给客户端。

---------------------------------------------------------------------------------------------

C# Java间进行RSA加密解密交互

C# Java间进行RSA加密解密交互(三)

 

转自:http://blog.csdn.net/dslinmy/article/details/37881067

抱歉!评论已关闭.