在网上找了很多的资料,一个一个试最终都没有解决问题。
后来凭感觉拼凑了一下别人的方法,解决java的RSA转C#的RSA,并通过测试。
//C# RSA 工具类
//要记得去下载BouncyCastle.Crypto.dll
class RSAUtil
{
/// <summary>
/// RSA encrypt
/// </summary>
/// <param name="publickey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static byte[] RSAEncryptCSharp(string publickey,string content)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(publickey);
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
//return Convert.ToBase64String(cipherbytes);
return cipherbytes;
}
/// <summary>
/// RSA decrypt
/// </summary>
/// <param name="privatekey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string RSADecryptCSharp(string privatekey,byte[] content)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(privatekey);
cipherbytes = rsa.Decrypt(content, false);
return Encoding.UTF8.GetString(cipherbytes);
}
/// <summary>
/// RSA encrypt
/// </summary>
/// <param name="publickey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static byte[] RSAEncryptJava(string publickey, string content)
{
publickey = RSAUtil.RSAPublicKeyJava2DotNet(publickey);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(publickey);
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
//return Convert.ToBase64String(cipherbytes);
return cipherbytes;
}
/// <summary>
/// RSA decrypt
/// </summary>
/// <param name="privatekey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string RSADecryptJava(string privatekey, byte[] content)
{
privatekey = RSAUtil.RSAPrivateKeyJava2DotNet(privatekey);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(privatekey);
cipherbytes = rsa.Decrypt(content, false);
return Encoding.UTF8.GetString(cipherbytes);
}
/// <summary>
/// RSA私钥格式转换,java->.net
/// </summary>
/// <param name="privateKey">java生成的RSA私钥</param>
/// <returns></returns>
public static string RSAPrivateKeyJava2DotNet(string privateKey)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
}
/// <summary>
/// RSA私钥格式转换,.net->java
/// </summary>
/// <param name="privateKey">.net生成的私钥</param>
/// <returns></returns>
public static string RSAPrivateKeyDotNet2Java(string privateKey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(privateKey);
BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));
RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
return Convert.ToBase64String(serializedPrivateBytes);
}
/// <summary>
/// RSA公钥格式转换,java->.net
/// </summary>
/// <param name="publicKey">java生成的公钥</param>
/// <returns></returns>
public static string RSAPublicKeyJava2DotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
}
/// <summary>
/// RSA公钥格式转换,.net->java
/// </summary>
/// <param name="publicKey">.net生成的公钥</param>
/// <returns></returns>
public static string RSAPublicKeyDotNet2Java(string publicKey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(publicKey);
BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
RsaKeyParameters pub = new RsaKeyParameters(false, m, p);
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
return Convert.ToBase64String(serializedPublicBytes);
}
}
//java RSA工具类
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.springframework.util.Base64Utils;
//StringUtil是个人封装的,暂不提供,下面要用到的时候,自己可以开发下
/**
* 功能描述:非对称算法-RSA,公钥加密-私钥解密,私钥加密-公钥解密
*/
public class RSA {
/**
* 密钥算法
*/
private static final String KEY_ALGORIGTHM = "RSA";
/**
*
*/
private static final String CIPHER_ALGORITHM_ECB1 = "RSA/ECB/PKCS1Padding";
/**
* 默认key长度
*/
private static final int DEFAULT_KEY_SIZE = 512;
/**
* 生成密钥对
*
* @return
* @throws Exception
*/
public static AsymmetricCryptionKey generatekey(int keySize) throws Exception {
if (keySize <= 0) {
keySize = DEFAULT_KEY_SIZE;
}
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORIGTHM);
// 设置密钥长度
keyPairGen.initialize(keySize);
KeyPair keyPair = keyPairGen.generateKeyPair();
return new AsymmetricCryptionKey(keyPair.getPublic(), keyPair.getPrivate());
}
/**
* 公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
return asymmetricCryptionByPublicKey(data, key, Cipher.ENCRYPT_MODE);
}
public static String encryptByPublicKey(String dataString, String keyString) throws Exception {
byte[] data = StringUtil.getBytes(dataString);//这里要自己实现下
byte[] key = toBytes(keyString);
byte[] revData = asymmetricCryptionByPublicKey(data, key, Cipher.ENCRYPT_MODE);
return toBase64String(revData);
}
/**
* 私钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
return asymmetricCryptionByPrivateKey(data, key, Cipher.ENCRYPT_MODE);
}
public static String encryptByPrivateKey(String dataString, String keyString) throws Exception {
byte[] data = StringUtil.getBytes(dataString);//这里要自己实现下
byte[] key = toBytes(keyString);
byte[] revData = asymmetricCryptionByPrivateKey(data, key, Cipher.ENCRYPT_MODE);
return toBase64String(revData);
}
/**
* 公钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
return asymmetricCryptionByPublicKey(data, key, Cipher.DECRYPT_MODE);
}
public static String decryptByPublicKey(String dataString, String keyString) throws Exception {
byte[] data = toBytes(dataString);
byte[] key = toBytes(keyString);
byte[] revData = asymmetricCryptionByPublicKey(data, key, Cipher.DECRYPT_MODE);
return new String(revData);
}
/**
* 私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
return asymmetricCryptionByPrivateKey(data, key, Cipher.DECRYPT_MODE);
}
public static String decryptByPrivateKey(String dataString, String keyString) throws Exception {
byte[] data = toBytes(dataString);
byte[] key = toBytes(keyString);
byte[] revData = asymmetricCryptionByPrivateKey(data, key, Cipher.DECRYPT_MODE);
return new String(revData);
}
/**
*
* @param data
* @return
*/
public static String toBase64String(byte[] data) {
if (data != null) {
return Base64Utils.encodeToString(data);
}
return null;
}
/**
*
* @param keyStr
* @return
*/
public static byte[] toBytes(String keyStr) {
if (!StringUtil.isNullOrEmpty(keyStr)) {//这里要自己实现下
return Base64Utils.decodeFromString(keyStr);
}
return null;
}
/**
* 公钥加密解密
*
* @param data
* @param key
* @param mode
* @return
* @throws Exception
*/
private static byte[] asymmetricCryptionByPublicKey(byte[] data, byte[] key, int mode) throws Exception {
// 取得公钥
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORIGTHM);
// 生成公钥
PublicKey pubKey = factory.generatePublic(new X509EncodedKeySpec(key));
// 加密或解密数据
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB1);
cipher.init(mode, pubKey);
return cipher.doFinal(data);
}
/**
* 私钥加密和解密
*
* @param data
* @param key
* @param mode
* @return
* @throws Exception
*/
private static byte[] asymmetricCryptionByPrivateKey(byte[] data, byte[] key, int mode) throws Exception {
// 取得 私钥
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORIGTHM);
PrivateKey priKey = factory.generatePrivate(new PKCS8EncodedKeySpec(key));
// 加密或解密数据
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB1);
cipher.init(mode, priKey);
return cipher.doFinal(data);
}
}
使用方法:
//C#加密
string encrypt = Convert.ToBase64String(RSAUtil.RSAEncryptJava("java的公钥", "你的加密内容"));
//java解密
String result = RSA.decryptByPrivateKey("C#公钥加密的内容", "java的私钥");