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

来源:互联网 发布:淘宝店铺月销量怎么看 编辑:程序博客网 时间:2024/05/21 04:42

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

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

/** * RSA加密 * @param text--待加密的明文 * @param key--公钥,由服务器端提供的经base64编码的字符串 * @return */public static String RSAEncryptoWithPublicKey(String text, String key) {String result = null;try {byte[] publicKeyByte = base64Decrypto(key);X509EncodedKeySpec x509 = new X509EncodedKeySpec(publicKeyByte);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey publicKey = keyFactory.generatePublic(x509);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);result = base64Encrypto(cipher.doFinal(text.getBytes()));} catch (Exception e) {e.printStackTrace();return null;}return result;}

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

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

import java.io.UnsupportedEncodingException;import java.lang.reflect.Method;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PublicKey;import java.security.interfaces.RSAPrivateCrtKey;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;/** * @author Administrator *  */public class RSAJavaToCSharp {public static void main(String[] args) throws Exception {HashMap<String, Object> map = getKeys();RSAPublicKey publicKey = (RSAPublicKey) map.get("PUBLIC");RSAPrivateKey privateKey = (RSAPrivateKey) map.get("PRIVATE");String publicKeyString = getRSAPublicKeyAsNetFormat(publicKey.getEncoded());String privateKeyString = getRSAPrivateKeyAsNetFormat(privateKey.getEncoded());System.out.println(encodeBase64(publicKey.getEncoded()));//此处为客户端加密时需要的公钥字符串System.out.println(encodePublicKeyToXml(publicKey));System.out.println(publicKeyString);System.out.println(privateKeyString);}/**获取密钥对 * @return * @throws NoSuchAlgorithmException */public static HashMap<String, Object> getKeys()throws NoSuchAlgorithmException {HashMap<String, Object> map = new HashMap<String, Object>();KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();map.put("PUBLIC", publicKey);map.put("PRIVATE", privateKey);return map;}/** * 私钥转换成C#格式 * @param encodedPrivkey * @return */private static String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivateKey) {try {StringBuffer buff = new StringBuffer(1024);PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);KeyFactory keyFactory = KeyFactory.getInstance("RSA");RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(pvkKeySpec);buff.append("<RSAKeyValue>");buff.append("<Modulus>"+ encodeBase64(removeMSZero(pvkKey.getModulus().toByteArray())) + "</Modulus>");buff.append("<Exponent>"+ encodeBase64(removeMSZero(pvkKey.getPublicExponent().toByteArray())) + "</Exponent>");buff.append("<P>"+ encodeBase64(removeMSZero(pvkKey.getPrimeP().toByteArray())) + "</P>");buff.append("<Q>"+ encodeBase64(removeMSZero(pvkKey.getPrimeQ().toByteArray())) + "</Q>");buff.append("<DP>"+ encodeBase64(removeMSZero(pvkKey.getPrimeExponentP().toByteArray())) + "</DP>");buff.append("<DQ>"+ encodeBase64(removeMSZero(pvkKey.getPrimeExponentQ().toByteArray())) + "</DQ>");buff.append("<InverseQ>"+ encodeBase64(removeMSZero(pvkKey.getCrtCoefficient().toByteArray())) + "</InverseQ>");buff.append("<D>"+ encodeBase64(removeMSZero(pvkKey.getPrivateExponent().toByteArray())) + "</D>");buff.append("</RSAKeyValue>");return buff.toString();} catch (Exception e) {System.err.println(e);return null;}}/** * 公钥转成C#格式 * @param encodedPrivkey * @return */private static String getRSAPublicKeyAsNetFormat(byte[] encodedPublicKey) {try {StringBuffer buff = new StringBuffer(1024);//Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keysKeyFactory keyFactory = KeyFactory.getInstance("RSA");RSAPublicKey pukKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(encodedPublicKey));buff.append("<RSAKeyValue>");buff.append("<Modulus>"+ encodeBase64(removeMSZero(pukKey.getModulus().toByteArray())) + "</Modulus>");buff.append("<Exponent>"+ encodeBase64(removeMSZero(pukKey.getPublicExponent().toByteArray())) + "</Exponent>");buff.append("</RSAKeyValue>");return buff.toString();} catch (Exception e) {System.err.println(e);return null;}}/** * 公钥转换成C#格式 * @param key * @return * @throws Exception */public static String encodePublicKeyToXml(PublicKey key) throws Exception {if (!RSAPublicKey.class.isInstance(key)) {return null;}RSAPublicKey pubKey = (RSAPublicKey) key;StringBuilder sb = new StringBuilder();sb.append("<RSAKeyValue>");sb.append("<Modulus>").append(encodeBase64(removeMSZero(pubKey.getModulus().toByteArray()))).append("</Modulus>");sb.append("<Exponent>").append(encodeBase64(removeMSZero(pubKey.getPublicExponent().toByteArray()))).append("</Exponent>");sb.append("</RSAKeyValue>");return sb.toString();}/** * @param data * @return */private static byte[] removeMSZero(byte[] data) {byte[] data1;int len = data.length;if (data[0] == 0) {data1 = new byte[data.length - 1];System.arraycopy(data, 1, data1, 0, len - 1);} elsedata1 = data;return data1;}/** * base64编码 * @param input * @return * @throws Exception */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;}/** * base64解码  * @param input * @return * @throws Exception */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;}public static String byteToString(byte[] b)throws UnsupportedEncodingException {return new String(b, "utf-8");}}

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

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

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

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

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

0 0
原创粉丝点击