C#中XML数字签名需用System.Security.Cryptography.Xml类配合RSA密钥对,关键步骤包括:构造SignedXml、添加Reference指定范围、应用EnvelopedTransform、ComputeSignature后插入节点;验证时用公钥调用CheckSignature。
在C#中给XML文件添加数字签名,核心是使用System.Security.Cryptography.Xml命名空间中的类(如SignedXml、Reference、XmlDsigEnvelopedSignatureTransform等),配合RSA或DSA密钥对完成签名与验证。关键在于正确构造签名结构、选择签名范围、指定引用URI和转换方式,并将签名写入XML文档的节点中。
XML数字签名必须使用非对称加密算法(推荐RSA)。你可以生成新密钥,也可加载已有的密钥容器或PFX证书:
RSA rsa = RSA.Create();
X509Certificate2 cert = new X509Certifica
te2("cert.pfx", "password"); RSA rsa = cert.GetRSAPrivateKey();
rsa.ExportParameters(false)获取)创建SignedXml实例后,需绑定XML文档、设置签名密钥,并明确签名目标(即要签名的XML片段):
new SignedXml(xmlDoc)关联DOM文档signedXml.SigningKey = rsa;注入私钥Reference指定签名范围:空URI("")表示整个文档;带ID的URI(如"#invoice1")需确保目标元素有id="invoice1"且ID属性被声明为xml:id或通过XmlDsigElementIdAttribute注册XmlDsigEnvelopedSignatureTransform,确保签名不包含自身(防循环引用)调用ComputeSignature()生成签名值、密钥信息和引用摘要,再用GetXml()获取签名节点,最后将其追加到原始XML文档中:
signedXml.ComputeSignature(); —— 执行哈希、加密、组装签名结构XmlElement signatureNode = signedXml.GetXml(); —— 获取标准... 元素xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(signatureNode, true)); —— 插入签名(注意深拷贝)xmlDoc.Save("signed.xml"),确保输出含签名且格式规范验证时只需公钥(甚至可仅用证书公钥部分),流程与签名类似但方向相反:
节点SignedXml docToVerify = new SignedXml(xmlDoc);,调用docToVerify.LoadXml(signatureNode);
docToVerify.CheckSignature(rsaPublicKey) 或 docToVerify.CheckSignature(cert)
true表示签名有效、内容未被篡改、密钥匹配不复杂但容易忽略细节:ID属性必须可被XPath识别、转换器要匹配签名场景(如Enveloped用于签名嵌在原文中)、时间戳和证书链验证需额外处理。生产环境建议结合X509Certificate2和可信CA证书提升信任等级。