前提:
需要调用JavaAPI进行签名/验签、加密/解密,需要使用BouncyCastle 类库进行Java与C#之间的数据互通。
加密理解点:
1:java 私钥采用的是PKCS8 ;C# 私钥采用的是PKCS1 格式
2:RSA加密 公钥加密,私钥解密或者私钥加密和公钥解密【这点和签名sign不同,sign需要私钥签名】
3:如果 java RSA加密 最后生成16进制 C# 也需要统一。这点一般需要确认最后生成的为base64还是16进制数据。
额外补充:
1:私钥,公钥注意去除空格,换行等(.Replace("\r", "").Replace("\n", "").Replace("\\s", ""))
2:加密 最后生成的一般为 byte数组 ,但是由于java中byte的范围在 [-128,127] 但是 C#中byte的范围在 [0,255]
并且使用byte不好进行对比传输,所以我们在进行签名或者加密时一般转化为字符串或者16进制。
BouncyCastle类库下载:
https://download.csdn.net/download/u011791378/11236710
******************以下时加密解密(C#与Java互通)BouncyCastle *************************
/// <summary>
/// 私钥加密2
/// </summary>
/// <param name="content">加密内容</param>
/// <param name="PrivateKey">PKCS8私钥</param>
/// <returns></returns>
public string EncryptByPrivateKey2(string content, string PrivateKey)
{
RsaKeyParameters PrivateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(PrivateKey));
var original = new BigInteger(Encoding.UTF8.GetBytes(content));
//加密
var encrypted = original.ModPow(PrivateKeyParam.Exponent, PrivateKeyParam.Modulus);
//16进制
return PayUtils.byteArray2HexString(encrypted.ToByteArray());
//base64
//return Convert.ToBase64String(encrypted.ToByteArray());
}
/// <summary>
/// 公钥解密2
/// </summary>
/// <param name="content">解密内容</param>
/// <param name="PublicKey">PKCS8公钥</param>
/// <returns></returns>
public string DecryptByPublicKey2(string content, string PublicKey)
{
//base64
//byte[] byteData = Convert.FromBase64String(content);
//16进制
var data = PayUtils.hexString2ByteArray(content);
RsaKeyParameters PublicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(PublicKey));
var encrypted = new BigInteger(data);
//解密
var decrypted = encrypted.ModPow(PublicKeyParam.Exponent, PublicKeyParam.Modulus);
return Encoding.UTF8.GetString(decrypted.ToByteArray());
}
/// <summary>
/// RSA公钥加密
/// </summary>
/// <param name="content">加密内容</param>
/// <param name="publickey">公钥</param>
/// <returns></returns>
public string EncryptByPublicKey(string content, string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
var original = new BigInteger(Encoding.UTF8.GetBytes(content));
//加密
var encrypted = original.ModPow(publicKeyParam.Exponent, publicKeyParam.Modulus);
//16进制
return PayUtils.byteArray2HexString(encrypted.ToByteArray());
//base64
//return Convert.ToBase64String(encrypted.ToByteArray());
}
/// <summary>
/// RSA私钥解密
/// </summary>
/// <param name="content">解密内容</param>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
public string DecryptByPrivateKey(string content, string privateKey)
{
//base64
//byte[] byteData = Convert.FromBase64String(content);
//16进制
var data = PayUtils.hexString2ByteArray(content);
RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
var encrypted = new BigInteger(data);
//解密
var decrypted = encrypted.ModPow(privateKeyParam.Exponent, privateKeyParam.Modulus);
return Encoding.UTF8.GetString(decrypted.ToByteArray());
}
*****************Bytes数组与16进制的转换*************************
private static readonly string hexChars = "0123456789ABCDEF";
/// <summary>
/// Bytes数组转为16进制
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string byteArray2HexString(byte[] data)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
byte lo = (byte)(0xF & data[i]);
byte hi = (byte)((int)((uint)(0xF0 & data[i]) >> 4));
sb.Append(hexChars.Substring(hi, 1)).Append(hexChars.Substring(lo, 1));
}
return sb.ToString();
}
/// <summary>
/// 16进制转为Bytes数组
/// </summary>
/// <param name="hexStr"></param>
/// <returns></returns>
public static byte[] hexString2ByteArray(String hexStr)
{
if (hexStr.Length % 2 != 0)
{
return null;
}
byte[] data = new byte[hexStr.Length / 2];
for (int i = 0; i < hexStr.Length / 2; i++)
{
char hc = hexStr.Substring(2 * i, 1).ToCharArray()[0];//.charAt(2 * i);
char lc = hexStr.Substring(2 * i + 1, 1).ToCharArray()[0];//.charAt(2 * i + 1);
byte hb = hexChar2Byte(hc);
byte lb = hexChar2Byte(lc);
if ((hb < 0) || (lb < 0))
{
return null;
}
int n = hb << 4;
data[i] = ((byte)(n + lb));
}
return data;
}
private static byte hexChar2Byte(char c)
{
if ((c >= '0') && (c <= '9'))
{
return (byte)(c - '0');
}
if ((c >= 'a') && (c <= 'f'))
{
return (byte)(c - 'a' + 10);
}
if ((c >= 'A') && (c <= 'F'))
{
return (byte)(c - 'A' + 10);
}
return 0;
}