C#使用 RSAWithSha256
注意这里需要安装 Portable.BouncyCastle
引用命名空间
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
public class RSAWithSha256
{
public static string privateKey = "私钥";
public static string publicKey = "公钥";
/// <summary>
/// </summary>
/// <param name="str">需签名的数据</param>
/// <param name="priKey">私钥</param>
/// <returns>签名后的值</returns>
public static string SignPrivate(string str, string priKey = null)
{
if (!string.IsNullOrWhiteSpace(priKey))
privateKey = priKey;
//SHA256withRSA
//根据需要加签时的哈希算法转化成对应的hash字符节
byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
var sha256 = new SHA256CryptoServiceProvider();
byte[] rgbHash = sha256.ComputeHash(bt);
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
key.FromXmlString(RSAPrivateKeyJava2DotNet(privateKey));
RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
formatter.SetHashAlgorithm("SHA256");//此处是你需要加签的hash算法,需要和上边你计算的hash值的算法一致,不然会报错。
byte[] inArray = formatter.CreateSignature(rgbHash);
return Convert.ToBase64String(inArray);
}
/// <summary>
/// 私钥解密
/// </summary>
/// <param name="ciphertext"></param>
/// <returns></returns>
public static string Decrypt(string ciphertext)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(RSAPrivateKeyJava2DotNet(privateKey));
Byte[] CiphertextData = Convert.FromBase64String(ciphertext);
int MaxBlockSize = rsa.KeySize / 8; //解密块最大长度限制
if (CiphertextData.Length <= MaxBlockSize)
return Encoding.Default.GetString(rsa.Decrypt(CiphertextData, false));
using (MemoryStream CrypStream = new MemoryStream(CiphertextData))
using (MemoryStream PlaiStream = new MemoryStream())
{
Byte[] Buffer = new Byte[MaxBlockSize];
int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
while (BlockSize > 0)
{
Byte[] ToDecrypt = new Byte[BlockSize];
Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);
Byte[] Plaintext = rsa.Decrypt(ToDecrypt, false);
PlaiStream.Write(Plaintext, 0, Plaintext.Length);
BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
}
return Encoding.Default.GetString(PlaiStream.ToArray());
}
}
}
/// <summary>
/// 公钥签名
/// </summary>
/// <param name="contentForSign"></param>
/// <param name="pubKey"></param>
/// <returns></returns>
public static string SignPublic(string contentForSign, string pubKey = null)
{
if (!string.IsNullOrWhiteSpace(pubKey))
publicKey = pubKey;
//转换成适用于.Net的秘钥
var netKey = RSAPublicKeyJava2DotNet(publicKey);
string encryptedContent = string.Empty;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(netKey);
var contentData = Encoding.UTF8.GetBytes(contentForSign);
int MaxBlockSize = rsa.KeySize / 8 - 11; //加密块最大长度限制
if (contentData.Length <= MaxBlockSize)
{
return Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(contentForSign), false));
}
using (MemoryStream PlaiStream = new MemoryStream(contentData))
using (MemoryStream CrypStream = new MemoryStream())
{
Byte[] Buffer = new Byte[MaxBlockSize];
int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
while (BlockSize > 0)
{
Byte[] ToEncrypt = new Byte[BlockSize];
Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);
Byte[] Cryptograph = rsa.Encrypt(ToEncrypt, false);
CrypStream.Write(Cryptograph, 0, Cryptograph.Length);
BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
}
return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
}
}
}
/// <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私钥格式转换,java->.net
/// </summary>
/// <param name="privatekey">java生成的私钥</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()));
}
}