[英]Verify SignatureValue And DigestValue Using Sha256 RSA
我正在尝试验证我在 C# 中收到的用于验证的数据。
这是我有的 XML,
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Response xmlns="http://www.site.ae/abc">
<Message xml:id="message">
<Header>
<SomeDate>SomValue</SomeDate>
</Header>
<Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SomeDataType">
<SomeStatus>Success</SomeStatus>
</Body>
</Message>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="#message">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</Response>
我正在使用下面的 C# 代码来验证上面的代码,
var signature = @"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var data = @"
<Header>
<SomeDate>SomValue</SomeDate>
</Header>
<Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:type=""SomeDataType"">
<SomeStatus>Success</SomeStatus>
</Body>";
var digest = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var x509Data = @"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX";
byte[] SignatureValueBytes = Convert.FromBase64String(signature);
byte[] x509DataBytes = Convert.FromBase64String(x509Data);
byte[] DigestValueBytes = Convert.FromBase64String(digest);
var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(x509DataBytes);
using (var rsa = System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPublicKey(cert))
{
bool a = rsa.VerifyHash(DigestValueBytes, SignatureValueBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
但是上面的代码无法验证。 我错过了什么? 这是空格问题吗?
XML 签名的创建,即 XML 文档( XMLDSig )的签名比普通签名的创建更复杂,因为一个相同的 Z3501BB093D363810B671059B9CFEDF 序列化在逻辑上是相同的,即不同的序列化序列化可以是不同的。 因此,XML 必须事先进行规范化,即转换为唯一格式( Canonicalization )。 同样,这同样适用于验证。
.NET 很大程度上封装了这些过程。 因此,签名比验证更复杂,因为对于后者,参数(例如规范化变体)包含在签名的 XML 中。
在问题中发布的签名 XML 中,已经嵌入了用于验证的密钥(即证书)。 在这种情况下,验证的可能实现是:
using System;
using System.Xml;
using System.Security.Cryptography.Xml;
public class VerifyTest
{
private static String signedXml =
@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""no""?>
<Response xmlns=""http://www.site.ae/abc"">
<Message id=""message"">
<Header>
<SomeDate>SomValue</SomeDate>
</Header>
<Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:type=""SomeDataType"">
<SomeStatus>Success</SomeStatus>
</Body>
</Message>
<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"">
<SignedInfo>
<CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments""/>
<SignatureMethod Algorithm=""http://www.w3.org/2001/04/xmldsig-more#rsa-sha256""/>
<Reference URI=""#message"">
<Transforms>
<Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/>
</Transforms>
<DigestMethod Algorithm=""http://www.w3.org/2001/04/xmlenc#sha256""/>
<DigestValue>hXuAfCAwKQIH1lGErMom2yO//25Pbyn1eXEmcEL1Rtk=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>izFP8eyDkG+9mDF2mAFl66174gpYbBzbcPPc/kDMjRm4TFnZdMAITLe60EPqdQAKK61A6FW8ZQrCkbbiBk/PRd8WaAxgAxjnMU8/U6gYUI6pk2LAANMquguYs7NQjURf7QFr1M1s7F1OrDDVlJiy2ZK3f0yLPoJstA+tnSbjYTQNlYP2qqzGARDkuEXZELSeCjXfA6M2gcGv7EsAv3GtgC2wR3GaVnnfLcieC+8bB9PJwkUtS3P/nmZuvezq/nBvZ/VsIgVjD/rLZX3rAxtVmhRj4d2ykGomnTBU0UJJtcIJyL3UJaQssr1U8YpSA5yWMfJ1uYUCZrGfh7OsHst/qrxeNwO0tGWAdsbD5MWYIwJzHAFcBTrNB0c6g1ehZwihBJWST2YJZvo3xV4UEO4++MhgsP0NHI8fPeBTZRx/vIN7quiJ21YxumUSwA5o8t4Rg9SSOthpnEbfyrSRntlSe8U28EdT0aNVL5gG/N5Qf3eW7XYHjJ2gxv8llMG6UcTY3ck48sW7f+ODatJ5Uk6GALFRjGgrdDlIBgImEormswDmwXSF46XoQVnEH2bR89Yd7g5GlzWQC+Fr5Q2vgVJ/ufS/85URVDr/KFYiJCzzmCEFdZWPR0zrOF/1GDbdAx0s8Zu3Sbq1ERMbdEQqxHs3N0NhdtVtYu96AXXnj5Azg3Y=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>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</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</Response>";
public static void Main(String[] args)
{
// Print XML document
Console.WriteLine(VerifyTest.signedXml);
// Load signed XML document
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(VerifyTest.signedXml);
// Verify
SignedXml signedXml = new SignedXml(xmlDoc);
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
signedXml.LoadXml((XmlElement)nodeList[0]);
bool verified = signedXml.CheckSignature();
Console.WriteLine(new string('-', 100) + "\nVerified: " + verified);
}
}
代码中包含的签名 XML 基于您发布的示例,我使用私有测试密钥对其进行了签名。 嵌入了验证所需并与私钥关联的证书。 代码可以在 .NET Fiddel 上在线运行: https://dotnetfiddle.net/xpjAz4 。
请注意, XmlDocument
class 具有PreserveWhitespace
属性,该属性默认为false
并控制在加载或保存时是否保留空格。 签名时,XML 文档的格式必须与此一致,同时考虑到PreserveWhitespace
标志。 在发布的代码中,使用默认值。
可以在此处找到使用嵌入式密钥进行签名的更多详细信息。 此处描述了验证。
编辑:
为了使用带有xml
前缀的id
属性,必须派生SignedXml
class 并且必须覆盖GetIdElement()
方法。 这个解决方案来自这篇文章,需要调整前缀和命名空间。 前缀xml
根据定义绑定到命名空间http://www.w3.org/XML/1998/namespace
,s。 W3C 建议,3 声明命名空间,命名空间约束:保留前缀和命名空间名称。
此外,当然,由于对xml:id
的修改,示例签名发生了变化,因此也需要替换,所以上面的代码片段整体更改为:
using System;
using System.Xml;
using System.Security.Cryptography.Xml;
public class VerifyTest
{
private static String signedXml =
@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""no""?>
<Response xmlns=""http://www.site.ae/abc"">
<Message xml:id=""message"">
<Header>
<SomeDate>SomValue</SomeDate>
</Header>
<Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:type=""SomeDataType"">
<SomeStatus>Success</SomeStatus>
</Body>
</Message>
<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"">
<SignedInfo>
<CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments""/>
<SignatureMethod Algorithm=""http://www.w3.org/2001/04/xmldsig-more#rsa-sha256""/>
<Reference URI=""#message"">
<Transforms>
<Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/>
</Transforms>
<DigestMethod Algorithm=""http://www.w3.org/2001/04/xmlenc#sha256""/>
<DigestValue>8anSzrELTpH8X6qq9rzTr6+T79EsRVhMLZ0ws3nYOTA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>IAxXS6JBw/DGI4BdAKBSuUWYD7vX8zA5yWnez6/D2B7o2DhpGLuZVVA6gqIf9cr0omk+5kwyQMStKoYm9JWhFU136XtMgx19WC/ZCvGa59LBpIUsVpr3IKm0cQasp4jMIyeQCbAi0R/fYCY3fdH6GWdMcPuh47oOM63mBUYarokUv0ypuPykZsH010VvS9Af42BPRjnSpFRLoY4E9YtkWNpNoEgIMFRCCC6xsH+mLjMVFAmldAAGHiYn1v847NmHR3qmjRd+tfn8YtxEeLLJNgNgg8+lE1C2wsCpBTowXi/LKngEEwL+pckaSxCFa6qLIDC8aOJHM9BN30lrvSAYFGfaNZ0SHECga6aQ05UgZrlMpCg56d65qqNBz0+kDEgFhCzr8CqftHfGcVGXm95k27qNrDsrPac8s16/LBzzhONAhEwMJ7Rlef27/xSl87RSOQWTJWLF6unsJBqWvpKJY+CP0mmezqCcN/Q28oETOrR8q4QaW7ByLLv5FH1O8nneJyfd2QmhDJ3XDBSWeTGlJEGPYztVWzz2qcq9jpKmzpYxMFOJS24SKQlKcKWAdGeRJVillTyANeDnSt1YOS/z2lQoWPzrNY1XCkBUdEA+pe0aFtX2X1JCKEqvS3AtRui8fZzQ+frhcC/Y/hYDO1mD3NliUH9zkcEm8PdGNBJaLIY=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>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</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</Response>";
public static void Main(String[] args)
{
// Print XML document
Console.WriteLine(VerifyTest.signedXml);
// Load signed XML document
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(VerifyTest.signedXml);
// Verify
SignedXmlWithId signedXml = new SignedXmlWithId(xmlDoc);
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
signedXml.LoadXml((XmlElement)nodeList[0]);
bool verified = signedXml.CheckSignature();
Console.WriteLine(new string('-', 100) + "\nVerified: " + verified);
}
class SignedXmlWithId : SignedXml
{
public SignedXmlWithId(XmlDocument xml) : base(xml) { }
public SignedXmlWithId(XmlElement xmlElement) : base(xmlElement) { }
public override XmlElement GetIdElement(XmlDocument doc, string id)
{
XmlElement idElem = base.GetIdElement(doc, id);
if (idElem == null)
{
XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
nsManager.AddNamespace("xml", "http://www.w3.org/XML/1998/namespace");
idElem = doc.SelectSingleNode("//*[@xml:id=\"" + id + "\"]", nsManager) as XmlElement;
}
return idElem;
}
}
}
现在 XML 示例与您发布的示例完全匹配,包括xml:id
属性。 代码片段可以成功执行,例如在线 .NET Fiddel: https://dotnetfiddle.net/nqNhu3 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.