C# Java RSA互通
Java代码
package com.pkuhit.mobile.pay.alipay.api.sign;
import com.founder.smc.util.Base64Util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
public class RSA{
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
/**
* RSA签名
* @param content 待签名数据
* @param privateKey 商户私钥
* @param input_charset 编码格式
* @return 签名值
*/
public static String sign(String content, String privateKey, String input_charset)
{
try
{
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update( content.getBytes(input_charset) );
byte[] signed = signature.sign();
return Base64.encode(signed);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* RSA验签名检查
* @param content 待签名数据
* @param sign 签名值
* @param ali_public_key 支付宝公钥
* @param input_charset 编码格式
* @return 布尔值
*/
public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
{
try
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decode(ali_public_key);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
signature.update( content.getBytes(input_charset) );
boolean bverify = signature.verify( Base64.decode(sign) );
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
/**
* 解密
* @param content 密文
* @param private_key 商户私钥
* @param input_charset 编码格式
* @return 解密后的字符串
*/
public static String decrypt(String content, String private_key, String input_charset) throws Exception {
PrivateKey prikey = getPrivateKey(private_key);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, prikey);
InputStream ins = new ByteArrayInputStream(Base64.decode(content));
ByteArrayOutputStream writer = new ByteArrayOutputStream();
//rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
byte[] buf = new byte[128];
int bufl;
while ((bufl = ins.read(buf)) != -1) {
byte[] block = null;
if (buf.length == bufl) {
block = buf;
} else {
block = new byte[bufl];
for (int i = 0; i < bufl; i++) {
block[i] = buf[i];
}
}
writer.write(cipher.doFinal(block));
}
return new String(writer.toByteArray(), input_charset);
}
/**
* 得到私钥
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = Base64.decode(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
/**
*加密
* @param content 明文
* @param public_key 公钥
* @param input_charset 编码格式(UTF-8)
* @return 加密后的字符串
* @throws Exception
*/
public static String encrypt(String content,String public_key, String input_charset) throws Exception {
PublicKey publicKey = getPublicKey(public_key);
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
ByteArrayOutputStream writer = new ByteArrayOutputStream();
//加密最大长度为117b(密钥长度为1024时),超过该长度的进行分块处理
byte[] encryptData = null;
byte[] con = content.getBytes("UTF-8");
byte[] cache;
int offSet = 0,i=0;
int dataLength = con.length;
while(dataLength - offSet > 0){
if (dataLength - offSet > 117){
cache = cipher.doFinal(con,offSet,117);
}else {
cache = cipher.doFinal(con,offSet,dataLength-offSet);
}
writer.write(cache,0,cache.length);
i++;
offSet = i*117;
}
encryptData = writer.toByteArray();
writer.close();
//先用RSA加密再用base64加密
return Base64Util.encode(encryptData);
}
/**
* 公钥字符串转PublicKey实例
* @param publicKey
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String publicKey) throws Exception {
byte[] publicKeyBytes = Base64Util.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
public static void main(String[] args)throws Exception {
String clientPrivateKey="";
String clientPublicKey="";
String context = "老铁";
String encryptData = encrypt(context,clientPublicKey,"UTF-8");
System.out.println("encryptData=>"+encryptData);
String decryptData = decrypt(encryptData,clientPrivateKey,"UTF-8");
System.out.println("decryptData=>"+decryptData);
}
}
C# 代码
public partial class RSAHelper
{
#region 私钥加密
/// <summary>
/// 基于Portable.BouncyCastle的RSA私钥加密
/// </summary>
/// <param name="privateKeyJava"></param>
/// <param name="data"></param>
/// <returns></returns>
public static string EncryptPrivateKeyJava(string privateKeyJava, string data, string encoding = "UTF-8")
{
RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyJava));
byte[] cipherbytes = Encoding.GetEncoding(encoding).GetBytes(data);
RsaEngine rsa = new RsaEngine();
rsa.Init(true, privateKeyParam);//参数true表示加密/false表示解密。
cipherbytes = rsa.ProcessBlock(cipherbytes, 0, cipherbytes.Length);
return Convert.ToBase64String(cipherbytes);
}
#endregion
#region 公钥解密
/// <summary>
/// 基于Portable.BouncyCastle的RSA公钥解密
/// </summary>
/// <param name="publicKeyJava"></param>
/// <param name="data"></param>
/// <param name="encoding"></param>
/// <returns></returns>
public static string DecryptPublicKeyJava(string publicKeyJava, string data, string encoding = "UTF-8")
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyJava));
byte[] cipherbytes = Convert.FromBase64String(data);
RsaEngine rsa = new RsaEngine();
rsa.Init(false, publicKeyParam);//参数true表示加密/false表示解密。
cipherbytes = rsa.ProcessBlock(cipherbytes, 0, cipherbytes.Length);
return Encoding.GetEncoding(encoding).GetString(cipherbytes);
}
#endregion
#region 加签
/// <summary>
/// 基于Portable.BouncyCastle的RSA签名
/// </summary>
/// <param name="data"></param>
/// <param name="privateKeyJava"></param>
/// <param name="hashAlgorithm">JAVA的和.NET的不一样,如:MD5(.NET)等同于MD5withRSA(JAVA)</param>
/// <param name="encoding"></param>
/// <returns></returns>
public static string RSASignJavaBouncyCastle(string data, string privateKeyJava, string hashAlgorithm = "SHA1WITHRSA", string encoding = "UTF-8")
{
RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyJava));
ISigner signer = SignerUtilities.GetSigner(hashAlgorithm);
signer.Init(true, privateKeyParam);//参数为true验签,参数为false加签
var dataByte = Encoding.GetEncoding(encoding).GetBytes(data);
signer.BlockUpdate(dataByte, 0, dataByte.Length);
//return Encoding.GetEncoding(encoding).GetString(signer.GenerateSignature()); //签名结果 非Base64String
return Convert.ToBase64String(signer.GenerateSignature());
}
#endregion
#region 验签
/// <summary>
/// 基于Portable.BouncyCastle的RSA签名
/// </summary>
/// <param name="data">源数据</param>
/// <param name="publicKeyJava"></param>
/// <param name="signature">base64签名</param>
/// <param name="hashAlgorithm">JAVA的和.NET的不一样,如:MD5(.NET)等同于MD5withRSA(JAVA)</param>
/// <param name="encoding"></param>
/// <returns></returns>
public static bool VerifyJavaBouncyCastle(string data, string publicKeyJava, string signature, string hashAlgorithm = "SHA1WITHRSA", string encoding = "UTF-8")
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyJava));
ISigner signer = SignerUtilities.GetSigner(hashAlgorithm);
signer.Init(false, publicKeyParam);
byte[] dataByte = Encoding.GetEncoding(encoding).GetBytes(data);
signer.BlockUpdate(dataByte, 0, dataByte.Length);
//byte[] signatureByte = Encoding.GetEncoding(encoding).GetBytes(signature);// 非Base64String
byte[] signatureByte = Convert.FromBase64String(signature);
return signer.VerifySignature(signatureByte);
}
#endregion
/// <summary>
/// RSA公钥加密
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private static string RSAEncrypt(string data)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(RSAPublicKeyJava2DotNet(PublicKey));
byte[] cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(data), RSAEncryptionPadding.OaepSHA1);
return Convert.ToBase64String(cipherbytes);
}
}
/// <summary>
/// RSA私钥解密
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private static string RSADecrypt(string data)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(RSAPrivateKeyJava2DotNet(PrivateKey));
byte[] cipherbytes = rsa.Decrypt(Convert.FromBase64String(data), RSAEncryptionPadding.OaepSHA1);
return Encoding.UTF8.GetString(cipherbytes);
}
}
/// <summary>
/// RSA公钥格式转换,java->.net
/// </summary>
/// <param name="publicKey">java生成的公钥</param>
/// <returns></returns>
private 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私钥格式转换,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()));
}
#region 登录密钥
/*
* 密钥对生成地址:http://web.chacuo.net/netrsakeypair 位数:2048 密钥格式:PKCS#8 输出格式:PEM/Base64
*/
private static readonly string PublicKey = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0/ViBSWEZQv6N3wGqNoW
Dw6hw1e+iFyrg2aoL7sFb67KEx6qJuWFQEwSjtv+aprEGmR3q35U9t0Z3dQzstSf
0nZ9Xq4GqDsq4bhBiBDhoKXJf0G4d4R7LeHXb95Z3Cu1IGtpATiC1nu/k5LbvSks
WaqpNPTqW0E6stUqijYq/dloAXGcyW1j5zWlK92RXTtEi/Rh35VqKqwI+zNsRoai
zV2HABPxmSLJ7cPUB9qNdvxX9amaKW/e7jfwhnokVQ+SvUiZqiOb77JEsdhyHyHm
+N3Pq7AsqI1V6/Z2aBv4i9aVXDml1yYtGk0ZfpUPkSOPaTsUoY09MFVFazGfUl+F
TQIDAQAB";
private static readonly string PrivateKey = @"MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDT9WIFJYRlC/o3
fAao2hYPDqHDV76IXKuDZqgvuwVvrsoTHqom5YVATBKO2/5qmsQaZHerflT23Rnd
1DOy1J/Sdn1ergaoOyrhuEGIEOGgpcl/Qbh3hHst4ddv3lncK7Uga2kBOILWe7+T
ktu9KSxZqqk09OpbQTqy1SqKNir92WgBcZzJbWPnNaUr3ZFdO0SL9GHflWoqrAj7
M2xGhqLNXYcAE/GZIsntw9QH2o12/Ff1qZopb97uN/CGeiRVD5K9SJmqI5vvskSx
2HIfIeb43c+rsCyojVXr9nZoG/iL1pVcOaXXJi0aTRl+lQ+RI49pOxShjT0wVUVr
MZ9SX4VNAgMBAAECggEAfCTf6WXE+q4eOrsw51r8yormYhSVaybj6g2JepNOptA4
WSR/wlJyTmt//x6JEAVf0JmBofdXalOr38p3EUoJ5eoyme7RxV0KS7Rw5XIFxOL1
dsyWb6Ivx3rchRA1j4gmCTv//5AKyfcnCRdeDpf7+vTDMFo2nYZCDBZgWR1K5uyL
CZw8d+ha6sVcN5ScusIwD0fu77ReDIaY1X0ekhaqrk7Ddnt16x7rO9C70HWWp2q3
iloeANxtyfvtUQtxzgBkch48/EztJX3rxFtdyYao9DkFeGOMu7gcVzNkFkzXPcBd
kt219eJctx56tE6G0uCXxON9XZtdQG/oTJlGtcqsHQKBgQD1Y3IdQCxnFtFqPsDm
TbAZ4eBeQtGiPtqFA7jfi0dSMe/qjQvB0k20ELrmW3pDBapYmajAUAEItTzSc85p
PZJ4PDFOvgOonaJkyE1bBlJHOaW6yKntZVMOGL0dtPEmM9Ova+Owxckzxc96H3wW
tUimBFQTwuKnCm/BX5zn2TJcQwKBgQDdH9qF8cF/uW1oPNZs5NqqZCGC4m4RsNFW
9j7FzIu7oQ3Xh+FxMRMv8t7LXzrgG5WXQh2RBWMicxlOqKTy/Zjl6C/LfS6bRtZR
Lmw0MGJI5oVwxfdcSRWV+ToxCi6GsmwvDyVaURX+3MGHvmFAt69UkqN0j54FxeDD
KqEUV65HLwKBgQCP1CsVxACCqBg0yvVrx8tZUFCfT1DqZSbV4hmhRVSXc9eoxeVH
RMnwqgGydZnS4OY4qlAD8KC6huhQfjpU6xcHzFgmTC9+zG5b3h+hI7JkNwDR2z3m
fIZS8+MdH2pdNvFzl6xMd5F3/BChBwVHlhgv3sedEZShzfc1A6LHLkJbWwKBgQDX
SLH6gps/fQrV15V0Q4PZLM+rnERJmPrXTbtj3HeW34CYfMSy7XKe1jivjDHIC1Mj
Bs2+aZ5Q5fqXqH2fzeNUwy/1UBVWPCtgsm/Kh+jIzRbR6wufn9ASSamsIRuXLJND
Zd2aByQBFHCfdm09ExjyoCnfzAuv1y2zFgfpxEv7JQKBgQCw7rPsOlh3EyUpYTeW
AOdPedHr8Xi1/ulnVPVVg2zXTSYoeiW+MwyY9B0Y0PvNtHzm3GURPya9IPKg/Wjo
57MbZFtIaOSBXBDCJZeeXVnthOVSYgjkRE6hU91t7sTqrzUrIZ21NTPjp2G1W2X2
QBJoRL5WTt04yIF6Hlkr3L+lww==";
#endregion
}

浙公网安备 33010602011771号