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

接着前面一篇文章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 keys
KeyFactory 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);
} else
data1 = 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加密解密交互(三)

C# Java间进行RSA加密解密交互(二)的更多相关文章

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

    原文:C# Java间进行RSA加密解密交互 这里,讲一下RSA算法加解密在C#和Java之间交互的问题,这两天纠结了很久,也看了很多其他人写的文章,颇受裨益,但没能解决我的实际问题,终于,还是被我捣 ...

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

    原文:C# Java间进行RSA加密解密交互(三) 接着前面一篇C# Java间进行RSA加密解密交互(二)说吧,在上篇中为了实现 /** * RSA加密 * @param text--待加密的明文 ...

  3. C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法

    因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...

  4. RSA加密解密与加签验签

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年7月首次在美国公布 ...

  5. Java & PHP & Javascript 通用 RSA 加密 解密 (长字符串)

    系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理:然而由于系统与系统之间的开发语言不同. 本次需求是生成二维码是通过java生成,由p ...

  6. java rsa加密解密

  7. RSA 加密 解密 (长字符串) JAVA JS版本加解密

    系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理:然而由于系统与系统之间的开发语言不同. 本次需求是生成二维码是通过java生成,由p ...

  8. RSA加密解密及数字签名Java实现--转

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院 ...

  9. Java使用RSA加密解密签名及校验

    RSA加密解密类: 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 32 33 ...

随机推荐

  1. 社区发现算法问题&&NetworkX&&Gephi

    在做东西的时候用到了社区发现,因此了解了一下有关社区发现的一些问题 1,社区发现算法 (1)SCAN:一种基于密度的社团发现算法 Paper: <SCAN: A Structural Clust ...

  2. Python数据结构——栈、队列的实现(一)

    1. 栈 栈(Stack)是限制插入和删除操作只能在一个位置进行的表,该位置是表的末端,称为栈的顶(top).栈的基本操作有PUSH(入栈)和POP(出栈).栈又被称为LIFO(后入先出)表. 1.1 ...

  3. html css布局

    这几天有点急于求成了,原来每一门技术都像大海,只有深入其中才发现它比看到的更要深广的多. 虽然忙里偷闲的看了HTML5,NODE.JS,JAVASCRIPT核心等许多东西,但是真正掌握的不足十分之一, ...

  4. MySQL ibdata1撑爆占满磁盘空间

    MySQL主从由于ibdata1占满磁盘空间-->主从失效 因为设置了innodb_file_per_table = 1,ibdata1依旧撑爆占满磁盘空间 主从断的时候,IO线程在连接,SQL ...

  5. Linux关机命令总结

    在linux命令中reboot是重新启动,shutdown -r now是立即停止然后重新启动,都说他们两个是一样的,其实是有一定的区别的. shutdown命令可以安全地关闭或重启Linux系统,它 ...

  6. 扒一扒各大电商网站的m站都用的什么前端技术输入日志标题

    凡客首页使用Swiper和zepto,没有使用jquery , 静态首页+js交互,  资源加载使用 lazyLoad X-AspNet-Version: 4.0.30319 X-AspNetMvc- ...

  7. IOS 控件的生命周期

    ViewController的生命周期包括: Initialize ViewDidLoad ViewWillAppear ViewDidAppear ViewWillDisappear ViewDid ...

  8. Java高效读取大文件

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...

  9. (转)assert()函数用法总结

    assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义: #include <assert.h>void assert( in ...

  10. 原型prototype -- 深入理解javascript

    /* 原型Prototype */ //一.原型 //原型使用一 var calculator = function (dlg, tax) { this.dlg = dlg; this.tax = t ...