zoukankan      html  css  js  c++  java
  • C# Java间进行RSA加密解密交互(二)

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

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

    [java] view plain copy
     
    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#的格式

    [java] view plain copy
     
    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(null, new 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加密解密交互(三)

  • 相关阅读:
    存储过程语法
    ORA-20000:ORU-10027:buffer overflow,limit of 2000 bytes.
    ORACLE 存储过程异常捕获并抛出
    Sqlldr导入txt文件内容到数据库中
    ORA-01589: 要打开数据库则必须使用 RESETLOGS 或 NORESETLOGS 选项
    oracle将一个表中字段的值赋值到另一个表中字段(批量)
    (三)Solr——Solr的基本使用
    (二)Solr——Solr界面介绍
    jrebel 7免费激活(非破解) 和 IntelliJ Idea 2017 免费激活方法
    (一)Solr——简介和安装配置
  • 原文地址:https://www.cnblogs.com/amylis_chen/p/8604970.html
Copyright © 2011-2022 走看看