重点说明:.net想要实现对PKCS8格式的私钥进行签名的话,需要使用类库:BouncyCastle.Crypto
下载地址:https://download.csdn.net/download/u011791378/11236710
1:生成公钥私钥,我直接使用的是支付宝官网上下载的RSA签名/验签的工具。
string privateKeyPem = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCTqFH65mTZLGmm5fWVbgSisLlYpIzWjmOu9lOG9ltH6Ia/Mn5Fnh2iRiYRGs8AzAoNgrOfWy6enK/5lvZa0VWxdw9Hq+mE11pEjh+vo3igvxsHw1Wp2f5cqhMgVT96V2WrSlha6IiQwvFQl72kQXx8sYsTk985OUX78VoUeD8OVXgU0bOXL2JrHfSRNzcQYV1QTrN67Mj6B3QIa4oLUGbB2wxW5jGtxAEOq+WrIyv9Y5IX7oqbHIDMc9L+VG89HnlEVot/Hca+6O1PoDGHygjFIyRXfwZzhaZz8BbAUJCQcWHg0CCY8S4Bj0gWnGiF+U0mezaHukyCZoiM3o3j7RZ5AgMBAAECggEAd82cJoyEysiEOIxghAut6yqkV827D+Kb8rud7eU5DtEVc1BOr8GonZ95B2vPBQCIL4oan3NmEf9jsIjR/cHXW5QUa7yKTeRFM1Z1Uxa5qwMjtVrByHw9K4Y62oMQa/05Wo+JvMjq9TmWfiOAFSOlE68h/pJ+DXnw1Ihw5CbkUoW+lfJkst1ZFSELatX8RMXLccuu06SzGKrnJYtGX3WtTXhs4ShCGuHqowQNzR8UyNPL5tJ1UQTeX8yi6NKkptcnb3IxPOCKDuogF97W/yEXeSxuC2UJfXEvc8fvEQ/D0MuhhWokK8oYoKJ0iMWkf7TeGJaWHB9+XcCJnlks7PXOmQKBgQDKYG1DT840M85qMQmEI+LzGZ348wbrF/JThLHqe66Wsyb+qlnrqRLADRY0u0BMQrQDLq/h2m/3YQ1rTkkHLVfjyi+SGb98JxqEIP1LZ9bzlY4lgfmhjjiGwspC4DFUg+QhyqUEEgziDlP74H4Io/dW1PVm45Hy9NcatDhPoXnPwwKBgQC6yDGpukUTDQ8fF7Ivd96xHzDTpVrGkLgucfosyFrazDBquAKkuyNd41PsOa+8a8Z2KYZQ2DI3Q4DQNeVsbQp3Ik+Q13hj9THfBN8zIE4td+T+uChit6D3fzJZv8F3Jc+IglbvFs/JEBL+5WjT4jtv7rCUJrw3Z0MnLS+mMRr5EwKBgHLg/eUh3jm/1sJtB6vc+y1oM0ZoHltBgqtqPdyPTPH6zH3vkY+2sBAY3awdR0iC7NCJpgmdB8Xzb7yj+cx7LtL9qLdUql/9io3KdD5juZ8YHFKqT1wn8Wp+FHaV8Sq6m7ua3sVKwclovL/UFXcuLG87//nh4K170scz2mtJjG4lAoGAeGS/9joVegEp5Q2+EfC+/wYuz80+pMz1myJmcmU2gt+oubEgKxRg6Iy2NIa+asJBazq60/N28r41EoAbAHeMjlv0U1U/yZZrbehTAj5phc9JMJJ9nZvlSoKXbtg2GNmrWr9Az92xU1VkGR7AIgsp6q087lHFciTCWUc79nCihTcCgYEAlzFctq2NosJduAivpeJZGR7i0mR1ciypJiKDllrkuvP5qKMYb6vKAGgvnMm9a5rdj32ejYtVZRZhU9pd50U9np/YbILu1sR/wXOzm4NCq7L4JDW/vJV+kMpkJu/mIRo00zp84+JGGjDCA3wvlQ/iVpa4hxPNjjlKfIlPLEIbMX8=";
string publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk6hR+uZk2SxppuX1lW4EorC5WKSM1o5jrvZThvZbR+iGvzJ+RZ4dokYmERrPAMwKDYKzn1sunpyv+Zb2WtFVsXcPR6vphNdaRI4fr6N4oL8bB8NVqdn+XKoTIFU/eldlq0pYWuiIkMLxUJe9pEF8fLGLE5PfOTlF+/FaFHg/DlV4FNGzly9iax30kTc3EGFdUE6zeuzI+gd0CGuKC1BmwdsMVuYxrcQBDqvlqyMr/WOSF+6KmxyAzHPS/lRvPR55RFaLfx3GvujtT6Axh8oIxSMkV38Gc4Wmc/AWwFCQkHFh4NAgmPEuAY9IFpxohflNJns2h7pMgmaIjN6N4+0WeQIDAQAB";
string signType = "RSA2";
记得要对公钥私钥去空格换行操作哦
注意:此处应该为PKCS8格式的私钥!!!
2:生成待签字符串
Dictionary<string, string> ParamInfo = new Dictionary<string, string>();
ParamInfo.Add("timestamp","20191112135000");
ParamInfo.Add("noncestr","123sdsf");
ParamInfo.Add("name", "张三");
//对报文中出现签名域(signature)之外的所有数据元按照key的ascii顺序排序,然后以&作为连接符拼接成待签名串。
string signContent = SignUtil.GetSignContent(ParamInfo);
生成待签字符串的可参考此方法
/// <summary>
/// 待签字符串
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
public static string GetSignContent(IDictionary<string, string> parameters)
{
// 第一步:把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder("");
while (dem.MoveNext())
{
string key = dem.Current.Key;
string value = dem.Current.Value;
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
{
query.Append(key).Append("=").Append(value).Append("&");
}
}
string content = query.ToString().Substring(0, query.Length - 1);
return content;
}
3:签名
string signatureNew = string.Empty;
string SignerSymbol = string.Empty;
if (signType == "RSA")
{
SignerSymbol = "SHA1WithRSA";
}
else
{
SignerSymbol = "SHA256WithRSA";
}
SignHelper helper = new SignHelper();
helper.RSASigning(Encoding.UTF8, SignerSymbol);
signatureNew = helper.Sign(signContent, privateKeyPem);
4:验签-不在签名步骤内。。。
bool check = false;
check=helper.Verify(signContent, signatureNew, publicKey);
check为true 则验签成功,为false则验签失败。
5:把签名放入报文集合中!这样整个报文才算签名完成。
SignHelper类库(需要引用BouncyCastle.Crypto)
public class SignHelper
{
public Encoding encoding = Encoding.UTF8;
public string SignerSymbol = "MD5withRSA";
public void RSASigning() { }
/// <summary>
/// 签名模式
/// </summary>
/// <param name="e">Encoding</param>
/// <param name="s">MD5withRSA,SHA256WithRSA</param>
public void RSASigning(Encoding e, string s)
{
encoding = e;
SignerSymbol = s;
}
private AsymmetricKeyParameter CreateKEY(bool isPrivate, string key)
{
byte[] keyInfoByte = Convert.FromBase64String(key);
if (isPrivate)
return PrivateKeyFactory.CreateKey(keyInfoByte);
else
return PublicKeyFactory.CreateKey(keyInfoByte);
}
/// <summary>
/// 数据加密
/// </summary>
/// <param name="content">待加密字符串</param>
/// /// <param name="privatekey">私钥</param>
/// <returns>加密后字符串</returns>
public string Sign(string content, string privatekey)
{
ISigner sig = SignerUtilities.GetSigner(SignerSymbol);
sig.Init(true, CreateKEY(true, privatekey));
byte[] bytes = encoding.GetBytes(content); //待加密字符串
sig.BlockUpdate(bytes, 0, bytes.Length);
byte[] signature = sig.GenerateSignature(); // Base 64 encode the sig so its 8-bit clean
var signedString = Convert.ToBase64String(signature);
return signedString;
}
/// <summary>
/// 验证签名
/// </summary>
/// <param name="content">待签名的字符串</param>
/// <param name="signData">加密后的文本</param>
/// <param name="publickey">公钥文本</param>
/// <returns>是否一致</returns>
public bool Verify(string content, string signData, string publickey)
{
ISigner signer = SignerUtilities.GetSigner(SignerSymbol);
signer.Init(false, CreateKEY(false, publickey));
var expectedSig = Convert.FromBase64String(signData);
var msgBytes = encoding.GetBytes(content);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(expectedSig);
}
}