SHA1WithRSA签名 规范化标准签名

it2026-02-24  9

#region CerRsaSignature 根据私钥签名 /// <summary> /// 根据私钥串签名 /// </summary> /// <param name="plainText">待签名的明文</param> /// <param name="prikeyPath">私钥证书路径</param> /// <param name="prikeyPassword">私钥证书密码</param> /// <param name="urid">签名uri</param> /// <returns></returns> public static ReturnValue CerRsaSignature(string prikeyPath, string prikeyPassword, string plainText,string urid) { ReturnValue retValue = new ReturnValue(); try { X509Certificate2 x509_Cer1 = new X509Certificate2(prikeyPath, prikeyPassword, X509KeyStorageFlags.Exportable); string key = x509_Cer1.PrivateKey.ToXmlString(true); ReturnValue signValue = CreateSign(plainText, urid, key); //签名失败 if (signValue.HasError) { retValue.HasError = true; retValue.Message = "签名失败"; return retValue; } retValue.HasError = signValue.HasError; retValue.Message = signValue.Message; return retValue; } catch (Exception ex) { retValue.HasError = true; retValue.Message = "签名异常" + ex.Message; log.WarnFormat("创建签名失败,签名数据:{0},错误原因:{1}", plainText, ex); return retValue; } }

/// <summary> /// 根据私钥证书XML串创建签名 /// </summary> /// <param name="privateKey">私钥证书XML串</param> /// <param name="plainText">待签名的明文</param> /// <param name="urid">签名uri</param> /// <returns></returns> public static ReturnValue CerRsaSignature(string privateKey, string plainText, string urid) { ReturnValue retValue = new ReturnValue(); try { ReturnValue signValue = CreateSign(plainText, urid, privateKey); //签名失败 if (signValue.HasError) { retValue.HasError = true; retValue.Message = "签名失败"; return retValue; } retValue.HasError = signValue.HasError; retValue.Message = signValue.Message; return retValue; } catch (Exception ex) { retValue.HasError = true; retValue.Message = "签名异常" + ex.Message; log.WarnFormat("创建签名失败,签名数据:{0},错误原因:{1}", plainText, ex); return retValue; } }

/// <summary> /// 创建签名 /// </summary> /// <param name="plainText"></param> /// <param name="urid"></param> /// <param name="key"></param> /// <returns></returns> private static ReturnValue CreateSign(string plainText, string urid, string key) { XmlDocument doc = new XmlDocument(); 创建CspParameters 对象并将私钥放入密钥容器中 //CspParameters cspParams = new CspParameters(); //cspParams.KeyContainerName = key;

// 创建一个新的RSA签名密钥并将其保存在容器。 RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(); rsaKey.FromXmlString(key); // 创建一个新的XML文档。 XmlDocument xmlDoc = new XmlDocument();

//将plainText加载到XmlDocument对象中。 xmlDoc.PreserveWhitespace = true; xmlDoc.LoadXml(plainText); // XML文档签名。 ReturnValue signValue = SignXml(xmlDoc, rsaKey, urid); return signValue; }

/// <summary> /// 计算签名 /// </summary> /// <param name="xmlDoc"></param> /// <param name="Key"></param> /// <param name="urid"></param> /// <returns></returns> private static ReturnValue SignXml(XmlDocument xmlDoc, RSA Key,string urid) { ReturnValue retValue = new ReturnValue(); //检查参数。 if (xmlDoc == null) { retValue.HasError = true; retValue.Message = "签名XML为空"; return retValue; } if (Key == null) { retValue.HasError = true; retValue.Message = "签名Key为空"; return retValue; } try {

// 创建一个signedxml对象 SignedXml signedXml = new SignedXml(xmlDoc); //添加添加到SignedXml的密钥 signedXml.SigningKey = Key;

指定标准化:http://www.w3.org/TR/2001/REC-xml-c14n-20010315 //signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl;

指定签名方法:rsa-sha1 //signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url; string uri = "#" + urid; // 创建一个引用来签名 Reference reference = new Reference(); reference.Uri = uri; //指定Signature标签与原xml报文的组装方式:enveloped XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // 添加到SignedXml对象添加参考。 signedXml.AddReference(reference); // 计算签名 signedXml.ComputeSignature(); // 得到签名的XML表示形式 XmlElement xmlDigitalSignature = signedXml.GetXml(); //xmlDigitalSignature.Prefix = "ds"; //SetPrefix("ds", xmlDigitalSignature); //添加元素的XML文档。 xmlDoc.DocumentElement.LastChild.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); //把签名加入到文档中 //xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); //获取SignatureValue标签的值,然后每76个字节增加一个换行 string signatureValue = xmlDoc.GetElementsByTagName("SignatureValue").Item(0).InnerText;

//设置xml文档中的SignatureValue标签的值 xmlDoc.GetElementsByTagName("SignatureValue").Item(0).InnerText = splitPer76AddLineBreak(signatureValue); retValue.HasError = false; retValue.Message = xmlDoc.OuterXml; return retValue;

} catch (Exception ex) { log.WarnFormat("创建签名失败,签名原文:{0},签名私钥:{1},错误原因:{2}", xmlDoc.InnerXml, Key.ToXmlString(true), ex.Message); retValue.HasError = true; retValue.Message = "创建签名异常"; return retValue; }

}

#endregion

/// <summary> /// 私有方法 /// </summary> /// <param name="prefix"></param> /// <param name="node"></param> private static void SetPrefix(String prefix, XmlNode node) { foreach (XmlNode n in node.ChildNodes) { SetPrefix(prefix, n); n.Prefix = prefix; } }

/// <summary> /// 对数据每76个字节增加一个换行符 /// </summary> /// <param name="message">待添加换行符的数据</param> /// <returns>添加换行符后的数据</returns> private static string splitPer76AddLineBreak(string message) {

//存储带有换行符的结果 StringBuilder sb = new StringBuilder();

//循环次数 int count = 0;

if (message.Length % 76 == 0) { count = message.Length / 76; } else { count = message.Length / 76 + 1; }

//截取字符串之后,还剩下没有截取的长度 int length = message.Length;

for (int i = 0; i < count; i++) {

//待截取的长度大于76时,增加换行符 if (length > 76) { sb.AppendLine(message.Substring(i * 76, 76)); } else {//不大于76,说明是最后一段 sb.Append(message.Substring(i * 76)); break; } length = message.Length - ((i + 1) * 76); }

return sb.ToString();

}

#region 验签方法 /// <summary> /// 根据公钥对返回数据进行验签 /// </summary> /// <param name="pubKeyPath">公钥路径</param> /// <param name="data">需要验签的数据</param> /// <returns></returns> public static ReturnValue VerifyXmlDoc(string pubKeyPath, string data) { ReturnValue retValue = new ReturnValue(); //创建XML对象 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; try { //将数据加载到XML对象中 xmlDoc.LoadXml(data); //读取公钥串 X509Certificate2 x509_Cer2 = new X509Certificate2(pubKeyPath); string publicKey = x509_Cer2.PublicKey.Key.ToXmlString(false); bool verify = VerifyXML(xmlDoc, publicKey); if (verify) { retValue.HasError = false; retValue.Message = "验签成功"; } else { retValue.HasError = true; retValue.Message = "验签失败"; } return retValue; } catch (Exception ex) { log.WarnFormat("验签异常:{0},银行返回数据:{1}", ex.Message, data); retValue.HasError = true; retValue.Message = "验签异常:" + ex.Message; return retValue; }

} /// <summary> /// 根据公钥证书XML串验证签名 /// </summary> /// <param name="publicKey"></param> /// <param name="xmlDoc"></param> /// <returns></returns> public static ReturnValue VerifyXmlDoc(string publicKey, XmlDocument xmlDoc) { ReturnValue retValue = new ReturnValue(); try { bool verify = VerifyXML(xmlDoc, publicKey); if (verify) { retValue.HasError = false; retValue.Message = "验签成功"; } else { retValue.HasError = true; retValue.Message = "验签失败"; } return retValue; } catch (Exception ex) { log.WarnFormat("验签异常:{0},银行返回数据:{1}", ex.Message, xmlDoc); retValue.HasError = true; retValue.Message = "验签异常:" + ex.Message; return retValue; } } /// <summary> /// 验证XmlDocument /// </summary> /// <param name="xmlDoc"></param> /// <param name="pubilcKey"></param> /// <returns></returns> private static bool VerifyXML(XmlDocument xmlDoc, string pubilcKey) { //创建加密服务提供者对象

RSACryptoServiceProvider csp = new RSACryptoServiceProvider();

//由通过 XML 字符串重新构造加密服务提供者对象

csp.FromXmlString(pubilcKey);

//创建XML签名对象

SignedXml sxml = new SignedXml(xmlDoc);

//得到签名元素的节点

XmlNode dsig = xmlDoc.GetElementsByTagName("Signature",

SignedXml.XmlDsigNamespaceUrl)[0];

sxml.LoadXml((XmlElement)dsig);

//验证签名是否正确,并且返回结果

bool verify = sxml.CheckSignature(csp); return verify; } #endregion

转载于:https://www.cnblogs.com/xinwuhen/p/5420640.html

相关资源:数据结构—成绩单生成器
最新回复(0)