

新闻资讯
技术学院SignedXml.ComputeSignature() 仅计算签名不自动插入,需手动调用 GetXml() 获取 Signature 节点并用 ImportNode 和 AppendChild 添加到文档;默认算法为不安全的 RSA-SHA1,应显式设为 RSA-SHA256;签名 XML 片段需用 Uri="#id" 和 XmlDsigEnvelopedSignatureTransform;验证失败多因变换不一致、空白处理差异或密钥不匹配。
GetXml() 拿不到 节点?因为 SignedXml.ComputeSignature() 只执行签名计算,不自动把生成的 插入原始文档。必须手动调用 SignedXml.GetXml() 获取签名节点,再用 D 和
ocument.ImportNode()Document.DocumentElement.AppendChild() 显式追加。
常见错误是直接保存原始 XmlDocument,结果 XML 里完全没签名内容。
doc.ImportNode(signatureNode, true) 导入节点(否则跨文档操作会抛 System.ArgumentException)SignedXml.Signature.Id 默认为 null,如果后续要引用该签名(如 Reference URI="#id"),需提前设值PreserveWhitespace = false),否则空白差异会导致验证失败SignedXml 默认使用 http://www.w3.org/2000/09/xmldsig#rsa-sha1(SHA-1 + RSA),但 SHA-1 已不安全。必须显式设置更安全的组合:
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; signedXml.SignedInfo.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
注意:DigestMethod 影响所有 Reference 的摘要计算;SignatureMethod 仅影响最终签名值生成。两者必须与密钥类型匹配(RSA 密钥不能配 ECDSA 算法)。
SHA1 或 MD5
sha384/sha512,但需确认下游系统兼容性X509Certificate2.PrivateKey 获取时,需确保证书含私钥且未标记为“不可导出”用 Reference.Uri 指向带 Id 属性的元素,例如签名 ...:
var reference = new Reference { Uri = "#payload" };
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
signedXml.AddReference(reference);
关键点在于:XmlDsigEnvelopedSignatureTransform 必须添加,否则签名时会把 自身也纳入摘要计算,导致验证永远失败。
Uri 值必须以 # 开头,且目标元素必须有 Id 属性(不是 id 或其他名称)Id 属性需声明为 xml:id 并注册 XmlNamespaceManager,否则 SignedXml 找不到它GetIdElement() 内部查找会返回 null
CryptographicException 原因验证失败抛 CryptographicException 通常不是算法错,而是上下文不一致:
EnvelopedSignature 变换,验证时没加 —— 验证代码也得调用 reference.AddTransform(new XmlDsigEnvelopedSignatureTransform())
XmlDocument.PreserveWhitespace = true,签名和验证两端空白处理不一致app.config 中启用兼容模式(不推荐,应改代码)最稳妥的验证方式是用 SignedXml.CheckSignature(certificate.PublicKey.Key) 显式传入公钥,绕过证书链验证逻辑。