rsa .net java_[原创]Java与.NET兼容的RSA密钥持久化方法

默认情况下,.NET生成的RSA密钥对可以用XML或字节流来保存,而JAVA中生成的RSA密钥对只能用字节流来保存。而它们的字节流格式不同,就导致Java中生成的RSA密钥对不能在.NET中使用,而.NET中生成的密钥对又不能在Java中使用。而.NET的XML保存方法我觉得比较有通用性,于是就以.NET中RSA密钥保存的XML格式作为兼容格式,这样它们就可以通用了。下面是Java代码:

PS:在Chrome上用博客园的编辑器设置不了代码折叠,保存后折叠的代码就打不开了。。。

=============================================

文件:StringHelper.java

字符串操作辅助类

文件:Base64Helper.java

Base64字符串和字节流互转的辅助类

文件:RsaHelper.java

代码中主要方法说明:

KeyPair generateRSAKeyPair();//生成密钥对

String encodePublicKeyToXml(PublicKey key);//将公钥转换为XML字符串

PublicKey decodePublicKeyFromXml(String xml);//从XML字符串得到公钥

String encodePrivateKeyToXml(PrivateKey key);//将私钥转换为XML字符串

PrivateKey decodePrivateKeyFromXml(String xml);//从XML字符串得到私钥

========================================================

StringHelper.java

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.*/

package com.scbeta.helpers;

/***

*@authoraaa*/

public class StringHelper {

//数组中是否包括某字符串    public static boolean arrayContainsString(String[] array, String key) {

for (String tmpString : array) {

if (tmpString.equals(key)) {

return true;

}

}

return false;

}

public static String GetLeftString(String source, String strTail) {

return GetLeftString(source, strTail, false);

}

public static String GetLeftString(String source, String strTail, boolean KeepHeadAndTail) {

return GetMiddleString(source, "", strTail, KeepHeadAndTail);

}

public static String GetRightString(String source, String strHead) {

return GetRightString(source, strHead, false);

}

public static String GetRightString(String source, String strHead, boolean KeepHeadAndTail) {

return GetMiddleString(source, strHead, "", KeepHeadAndTail);

}

public static String GetMiddleString(String source, String strHead, String strTail) {

return GetMiddleString(source, strHead, strTail, false);

}

public static String GetMiddleString(String source, String strHead, String strTail, boolean KeepHeadAndTail) {

try {

int indexHead, indexTail;

if (strHead == null || strHead.isEmpty()) {

indexHead = 0;

} else {

indexHead = source.indexOf(strHead);

}

if (strTail == null || strTail.isEmpty()) {

indexTail = source.length();

} else {

indexTail = source.indexOf(strTail, indexHead + strHead.length());

}

if (indexTail 

indexTail = source.length();

}

String rtnStr = "";

if ((indexHead >= 0) && (indexTail >= 0)) {

if (KeepHeadAndTail) {

rtnStr = source.substring(indexHead, indexTail + strTail.length());

} else {

rtnStr = source.substring(indexHead + strHead.length(), indexTail);

}

}

return rtnStr;

} catch (Exception ex) {

return "";

}

}

}

Base64Helper.java:

package com.scbeta.helpers;

import java.io.IOException;

public class Base64Helper {

public static String encode(byte[] byteArray) {

sun.misc.BASE64Encoder base64Encoder = new sun.misc.BASE64Encoder();

return base64Encoder.encode(byteArray);

}

public static byte[] decode(String base64EncodedString) {

sun.misc.BASE64Decoder base64Decoder = new sun.misc.BASE64Decoder();

try {

return base64Decoder.decodeBuffer(base64EncodedString);

} catch (IOException e) {

return null;

}

}

}

RsaHelper.java:

//===================

//作者:aaaSoft//日期:2011年11月30日//博客:http://www.cnblogs.com/aaaSoft///Email:scbeta@qq.com//说明:原创文章,转载请注明出处并保留作者信息//===================

package com.scbeta.helpers.security;

import java.math.BigInteger;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.NoSuchAlgorithmException;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Signature;

import java.security.interfaces.RSAPrivateCrtKey;

import java.security.interfaces.RSAPublicKey;

import java.security.spec.RSAPrivateCrtKeySpec;

import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;

import com.scbeta.helpers.Base64Helper;

import com.scbeta.helpers.StringHelper;

public class RsaHelper {

/*** 生成RSA密钥对(默认密钥长度为1024)

*

*@return*/

public static KeyPair generateRSAKeyPair() {

return generateRSAKeyPair(1024);

}

/*** 生成RSA密钥对

*

*@paramkeyLength

*            密钥长度,范围:512~2048

*@return*/

public static KeyPair generateRSAKeyPair(int keyLength) {

try {

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");

kpg.initialize(keyLength);

return kpg.genKeyPair();

} catch (NoSuchAlgorithmException e) {

return null;

}

}

public static String encodePublicKeyToXml(PublicKey key) {

if (!RSAPublicKey.class.isInstance(key)) {

return null;

}

RSAPublicKey pubKey = (RSAPublicKey) key;

StringBuilder sb = new StringBuilder();

sb.append("");

sb.append("")

.append(Base64Helper.encode(pubKey.getModulus().toByteArray()))

.append("");

sb.append("")

.append(Base64Helper.encode(pubKey.getPublicExponent()

.toByteArray())).append("");

sb.append("");

return sb.toString();

}

public static PublicKey decodePublicKeyFromXml(String xml) {

xml = xml.replaceAll("\r", "").replaceAll("\n", "");

BigInteger modulus = new BigInteger(1, Base64Helper.decode(StringHelper

.GetMiddleString(xml, "", "")));

BigInteger publicExponent = new BigInteger(1,

Base64Helper.decode(StringHelper.GetMiddleString(xml,

"", "")));

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus,

publicExponent);

KeyFactory keyf;

try {

keyf = KeyFactory.getInstance("RSA");

return keyf.generatePublic(rsaPubKey);

} catch (Exception e) {

return null;

}

}

public static PrivateKey decodePrivateKeyFromXml(String xml) {

xml = xml.replaceAll("\r", "").replaceAll("\n", "");

BigInteger modulus = new BigInteger(1, Base64Helper.decode(StringHelper

.GetMiddleString(xml, "", "")));

BigInteger publicExponent = new BigInteger(1,

Base64Helper.decode(StringHelper.GetMiddleString(xml,

"", "")));

BigInteger privateExponent = new BigInteger(1,

Base64Helper.decode(StringHelper.GetMiddleString(xml, "",

"")));

BigInteger primeP = new BigInteger(1, Base64Helper.decode(StringHelper

.GetMiddleString(xml, "

", "

")));

BigInteger primeQ = new BigInteger(1, Base64Helper.decode(StringHelper

.GetMiddleString(xml, "", "")));

BigInteger primeExponentP = new BigInteger(1,

Base64Helper.decode(StringHelper.GetMiddleString(xml, "",

"")));

BigInteger primeExponentQ = new BigInteger(1,

Base64Helper.decode(StringHelper.GetMiddleString(xml, "",

"")));

BigInteger crtCoefficient = new BigInteger(1,

Base64Helper.decode(StringHelper.GetMiddleString(xml,

"", "")));

RSAPrivateCrtKeySpec rsaPriKey = new RSAPrivateCrtKeySpec(modulus,

publicExponent, privateExponent, primeP, primeQ,

primeExponentP, primeExponentQ, crtCoefficient);

KeyFactory keyf;

try {

keyf = KeyFactory.getInstance("RSA");

return keyf.generatePrivate(rsaPriKey);

} catch (Exception e) {

return null;

}

}

public static String encodePrivateKeyToXml(PrivateKey key) {

if (!RSAPrivateCrtKey.class.isInstance(key)) {

return null;

}

RSAPrivateCrtKey priKey = (RSAPrivateCrtKey) key;

StringBuilder sb = new StringBuilder();

sb.append("");

sb.append("")

.append(Base64Helper.encode(priKey.getModulus().toByteArray()))

.append("");

sb.append("")

.append(Base64Helper.encode(priKey.getPublicExponent()

.toByteArray())).append("");

sb.append("

")

.append(Base64Helper.encode(priKey.getPrimeP().toByteArray()))

.append("

");

sb.append("")

.append(Base64Helper.encode(priKey.getPrimeQ().toByteArray()))

.append("");

sb.append("")

.append(Base64Helper.encode(priKey.getPrimeExponentP()

.toByteArray())).append("");

sb.append("")

.append(Base64Helper.encode(priKey.getPrimeExponentQ()

.toByteArray())).append("");

sb.append("")

.append(Base64Helper.encode(priKey.getCrtCoefficient()

.toByteArray())).append("");

sb.append("")

.append(Base64Helper.encode(priKey.getPrivateExponent()

.toByteArray())).append("");

sb.append("");

return sb.toString();

}

//用公钥加密    public static byte[] encryptData(byte[] data, PublicKey pubKey) {

try {

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, pubKey);

return cipher.doFinal(data);

} catch (Exception e) {

return null;

}

}

//用私钥解密    public static byte[] decryptData(byte[] encryptedData, PrivateKey priKey) {

try {

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, priKey);

return cipher.doFinal(encryptedData);

} catch (Exception e) {

return null;

}

}

/*** 根据指定私钥对数据进行签名(默认签名算法为"SHA1withRSA")

*

*@paramdata

*            要签名的数据

*@parampriKey

*            私钥

*@return*/

public static byte[] signData(byte[] data, PrivateKey priKey) {

return signData(data, priKey, "SHA1withRSA");

}

/*** 根据指定私钥和算法对数据进行签名

*

*@paramdata

*            要签名的数据

*@parampriKey

*            私钥

*@paramalgorithm

*            签名算法

*@return*/

public static byte[] signData(byte[] data, PrivateKey priKey,

String algorithm) {

try {

Signature signature = Signature.getInstance(algorithm);

signature.initSign(priKey);

signature.update(data);

return signature.sign();

} catch (Exception ex) {

return null;

}

}

/*** 用指定的公钥进行签名验证(默认签名算法为"SHA1withRSA")

*

*@paramdata

*            数据

*@paramsign

*            签名结果

*@parampubKey

*            公钥

*@return*/

public static boolean verifySign(byte[] data, byte[] sign, PublicKey pubKey) {

return verifySign(data, sign, pubKey, "SHA1withRSA");

}

/***

*@paramdata 数据

*@paramsign 签名结果

*@parampubKey 公钥

*@paramalgorithm 签名算法

*@return*/

public static boolean verifySign(byte[] data, byte[] sign,

PublicKey pubKey, String algorithm) {

try {

Signature signature = Signature.getInstance(algorithm);

signature.initVerify(pubKey);

signature.update(data);

return signature.verify(sign);

} catch (Exception ex) {

return false;

}

}

}

==============================

下面是测试代码:

public static void main(String[] args) {

KeyPair kp = RsaHelper.generateRSAKeyPair();

PublicKey pubKey = kp.getPublic();

PrivateKey priKey = kp.getPrivate();

String pubKeyXml = RsaHelper.encodePublicKeyToXml(pubKey);

String priKeyXml = RsaHelper.encodePrivateKeyToXml(priKey);

System.out.println("====公钥====");

System.out.println(pubKeyXml);

System.out.println("====私钥====");

System.out.println(priKeyXml);

PublicKey pubKey2 = RsaHelper.decodePublicKeyFromXml(pubKeyXml);

PrivateKey priKey2 = RsaHelper.decodePrivateKeyFromXml(priKeyXml);

System.out.println("====公钥对比====");

System.out.println(pubKey.toString());

System.out.println("------");

System.out.println(pubKey2.toString());

System.out.println("====私钥对比====");

System.out.println(priKey.toString());

System.out.println("------");

System.out.println(priKey2.toString());

try {

String pubKeyXml3 = "rHESyuI3ny4MLsqDBalW9ySaodCL0e6Bsrl01Q5G1qm2wjUoGULazZSNqZY+JQNjU92tW3Snk5RPIkv+wDj+uOT9LTUjQImltHnzqMvbt06GipVXDOyBLTa7G/zRIe/CrjyJ+XEYX2xIhpe5ayowl3HHUpZ71jRNioyxaVVZ8S0=AQAB";

String priKeyXml3 = "rHESyuI3ny4MLsqDBalW9ySaodCL0e6Bsrl01Q5G1qm2wjUoGULazZSNqZY+JQNjU92tW3Snk5RPIkv+wDj+uOT9LTUjQImltHnzqMvbt06GipVXDOyBLTa7G/zRIe/CrjyJ+XEYX2xIhpe5ayowl3HHUpZ71jRNioyxaVVZ8S0=AQAB

5a7uM+IeY8QMVQl0q88ZTqWbB555l7+366cUIClTN8z2ZXzTnWFCNoQzUrG14FouJFYumFZD12Ni5MkJK6gqSw==

wDMhwwO4kz82uSG+FlCBr06fYk2COTg0TofmSp/5OrVqgkBIe7FgpTpVGzGLk0mvOLcy6UZftq//W0Saow6nZw==FbjDgliiMyE5YVlxlUYSyKNU1BWivj09caXte1UtL5vMubBiewHVtz4tdGamIr+kmX8lDPcrl1Uo5yY0HdLbnQ==kIjjJsgxkWnEOUyKqjU4kSDK8x3ehDEkBLpmEFBlGCU9R14YJAyr5RUM0zpbABQ1VK1P9+UYLUYE/hmFQIHQmQ==pxQDThwSnUZ4EaNaCPl1ovYypdQUZaZ/Sld1+0n8FEjkmRcGP1R9VMuj1ViPZg3rvm2GeP8Xv1SJqJUVueWiGA==DxBNoPWEAF7IZ6n/KhZx52MGMw6BuFQKdm9m+lml7Iik03BLUXGapYzNlzvtr9QM8D2UMEIPhX/WLdvPpEEWVzGnD7XpLXjGwfu1ZkJRcXPEZEZ2subh5ZBqOWCFWKv5WwgGYWuYDLHfrBlBgSFWR8cZuyqkmMsWl4CiadXqGA0=";

System.out.println((new Date()).toLocaleString() + ": 加载公钥中。。。");

PublicKey pubKey3 = RsaHelper.decodePublicKeyFromXml(pubKeyXml3);

System.out.println((new Date()).toLocaleString() + ": 加载私钥中。。。");

PrivateKey priKey3 = RsaHelper.decodePrivateKeyFromXml(priKeyXml3);

String dataStr = "Java与.NET和平共处万岁!";

byte[] dataByteArray = dataStr.getBytes("utf-8");

System.out.println("data的Base64表示:"

+ Base64Helper.encode(dataByteArray));

System.out.println((new Date()).toLocaleString() + ": 加密中。。。"); //加密            byte[] encryptedDataByteArray = RsaHelper.encryptData(

dataByteArray, pubKey3);

System.out.println("encryptedData的Base64表示:"

+ Base64Helper.encode(encryptedDataByteArray));

System.out.println((new Date()).toLocaleString() + ": 解密中。。。"); //解密//byte[]            byte[] decryptedDataByteArray = RsaHelper.decryptData(

encryptedDataByteArray, priKey3);

System.out.println(new String(decryptedDataByteArray, "utf-8"));//签名            System.out.println((new Date()).toLocaleString() + ": 签名中。。。");

byte[] signDataByteArray = RsaHelper.signData(dataByteArray,

priKey3);

System.out.println("signData的Base64表示:"

+ Base64Helper.encode(signDataByteArray)); //验签            System.out.println((new Date()).toLocaleString() + ": 验签中。。。");

boolean isMatch = RsaHelper.verifySign(dataByteArray,

signDataByteArray, pubKey3);

System.out.println("验签结果:" + isMatch);

} catch (Exception ex) {

ex.printStackTrace();

}

}

最后,补充一段C#产生密钥对的代码片段如下:

usingSystem.Security.Cryptography;//密钥位数

int keySize = 1024;//产生密钥对

RSACryptoServiceProvider rSACryptoServiceProvider = newRSACryptoServiceProvider(keySize);//得到公钥

String publicKey = rSACryptoServiceProvider.ToXmlString(false);//得到私钥

String privateKey = rSACryptoServiceProvider.ToXmlString(true);

附上我用C#编写的“RSA密钥对生成器”,点此下载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值