C# RSA加解密与验签,AES加解密,以及与JAVA平台的密文加解密

时间:2021-08-20 10:43:44

前言:

RSA算法是利用公钥与密钥对数据进行加密验证的一种算法。一般是拿私钥对数据进行签名,公钥发给友商,将数据及签名一同发给友商,友商利用公钥对签名进行验证。也可以使用公钥对数据加密,然后用私钥对数据进行解密。

.Net平台生成的RSA公私钥是xml格式的,java平台下一般是使用der或者pem格式的公私钥,pem格式就是比der格式多了-----BEGIN PUBLIC KEY-----开头及结尾。

.Net平台要使用der/pem公私钥要先转换成xml格式,这需要用到 BouncyCastle.Crypto 这个开源dll,网上已经很多例子。也可以用该dll将.Net生成的公私钥转换成Java平台使用的公私钥。

AES加解密的数据也能在.Net平台和Java平台下互相加解密。

以下.net代码加密的数据皆能在java环境中验证或解密,反之亦然。

---------------------------------------------------------------------------------------------------

     /// <summary>
/// Xml转换成Der,传入公钥文件格式
/// </summary>
/// <param name="publickey"></param>
/// <returns></returns>
private byte[] RSAPublicKeytoJava(string publickey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(publickey);
BigInteger m = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[].InnerText));
BigInteger p = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[].InnerText));
RsaKeyParameters pub = new RsaKeyParameters(false, m, p); SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
return serializedPublicBytes;
}
     /// <summary>
/// Xml转换成Der,传入私钥文件格式
/// </summary>
/// <param name="privateKey"></param>
/// <returns></returns>
private byte[] RSAPrivateKeytoJava(string privateKey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(privateKey);
BigInteger m = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[].InnerText));
BigInteger exp = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[].InnerText));
BigInteger d = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[].InnerText));
BigInteger p = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[].InnerText));
BigInteger q = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[].InnerText));
BigInteger dp = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[].InnerText));
BigInteger dq = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[].InnerText));
BigInteger qinv = new BigInteger(, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[].InnerText)); RsaPrivateCrtKeyParameters privateParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv); var publicKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateParam);
byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
return serializedPublicBytes;
}
     /// <summary>
/// rsa公钥加密
/// </summary>
/// <param name="privateKeyfile"></param>
/// <param name="text"></param>
/// <returns></returns>
private string RsaEncry(string privateKeyfile, string text)
{
var pubKey = File.ReadAllText(this.pubPath); var rsa = new RSACryptoServiceProvider(rsaSize);
rsa.FromXmlString(pubKey); var bytesToEncrypt = Encoding.Unicode.GetBytes(text);
var encrypt = rsa.Encrypt(bytesToEncrypt, false);
return Convert.ToBase64String(encrypt);
}
    /// <summary>
/// RSA私钥解密
/// </summary>
/// <param name="privateKey">私钥文件</param>
/// <param name="text">待解密字符串</param>
/// <returns></returns>
private string RsaDecry(string privateKey,string text)
{
var provider = new RSACryptoServiceProvider(this.rsaSize);
provider.FromXmlString(privateKey);
var bytesEncrypted = Convert.FromBase64String(text);
var bytesPlainText = provider.Decrypt(bytesEncrypted, false);
return Encoding.Unicode.GetString(bytesPlainText);
}
    /// <summary>
/// RSA签名
/// </summary>
/// <param name="text">待加密文本</param>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
private string RsaSign(string text, string privateKey)
{
var bytesToEncrypt = Encoding.UTF8.GetBytes(text);
var rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privateKey);
var sha = SHA256.Create();
var encrypt = rsa.SignData(bytesToEncrypt, sha);
return Convert.ToBase64String(encrypt);
}
  /// <summary>
/// rsa验证签名
/// </summary>
/// <param name="txt">明文</param>
/// <param name="sign">签名串</param>
/// <param name="pubKey">公钥</param>
/// <returns></returns>
private bool RsaVerifyData(string txt, string sign, string pubKey)
{
var soures = Encoding.UTF8.GetBytes(txt);
var bytes = Convert.FromBase64String(sign); var rsa = new RSACryptoServiceProvider(rsaSize);
rsa.FromXmlString(pubKey);
SHA256 sha = SHA256.Create(); return rsa.VerifyData(soures, sha, bytes);
}
 /// <summary>
/// AES加密
/// </summary>
/// <param name="text">加密字符串</param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
private string AESEncry(string text, string key, string iv)
{
var bytes = Encoding.UTF8.GetBytes(text);
var keyBytes = new byte[];
var pwkBytes = Encoding.UTF8.GetBytes(key);
//注意这段代码,很重要,没有则java验证不通过
var len = pwkBytes.Length;
if (len > keyBytes.Length)
len = keyBytes.Length; Array.Copy(pwkBytes, keyBytes, len);
var rm = new RijndaelManaged
{
Key = keyBytes,
Mode = CipherMode.CBC,
IV = Encoding.UTF8.GetBytes(iv),
Padding = PaddingMode.PKCS7,
};
var tramsform = rm.CreateEncryptor();
var rst = tramsform.TransformFinalBlock(bytes, , bytes.Length);
return Convert.ToBase64String(rst);
}
        /// <summary>
/// AES解密
/// </summary>
/// <param name="text">解密字符串</param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
private string AesDecry(string text, string key, string iv)
{
var bytes = Convert.FromBase64String(text); var keyBytes = new byte[];
var pwkBytes = Encoding.UTF8.GetBytes(key);
var len = pwkBytes.Length;
if (len > keyBytes.Length)
len = keyBytes.Length;
Array.Copy(pwkBytes, keyBytes, len); var rm = new RijndaelManaged()
{
Key = keyBytes,
Mode = CipherMode.CBC,
IV = Encoding.UTF8.GetBytes(iv),
Padding = PaddingMode.PKCS7
};
var transform = rm.CreateDecryptor();
var rst = transform.TransformFinalBlock(bytes, , bytes.Length);
return Encoding.UTF8.GetString(rst);
}

这有一篇数字证书的原理文章写得比较清楚:数字证书原理(ssl,https)