我想通過使用自簽名X.509證書使用SHA256簽名XML。我在#1啓發了許多文章,並使用此代碼:如何正確使用SHA256&X.509簽名XML?
X509Certificate2 cert = new X509Certificate2();
X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 cert2 in store.Certificates)
{
if (cert2.Subject == "CN=TestCerificate")
{
cert = cert2;
break;
}
}
store.Close();
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
var exportedKeyMaterial = cert.PrivateKey.ToXmlString(true);
var key = new RSACryptoServiceProvider(new CspParameters(24));
key.PersistKeyInCsp = false;
key.FromXmlString(exportedKeyMaterial);
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load("test.xml");
SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
Reference reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
doc.Save("testSig.xml");
之後,的「testSig.xml」生成的XML簽名的部分看起來像這樣:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>ghOEPeYtAUs5Kb8VMOCIS3f2wIY=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>HANI0GrICbyc5tlmvtU9cB7txdxtuY4uDsntp5XVzaRQbts76ff3Qg==</SignatureValue>
</Signature>
正如你所看到的XML說「SHA1」用於簽名XML(參見節點「SignatureMethod」&「DigestMethod」)。但我期望,SHA256-URL必須在這些節點中說明。這個假設是否正確?如果是的話,是否有人知道如何解決這個問題?我使用C#4.6.0。
與問候, 邁克爾
您寫的代碼會生成簽名,但不會將其放入文檔(是否預先簽名?)。您錯過了對'GetXml()'的調用並將該節點插入到文檔中。 – bartonjs
謝謝,這幫助我解決了我的問題。實際上,我忘了將已簽名的XML-Node添加到我的xml文件中。來自上面的「錯誤」簽名的xml部分來自另一個意外執行的代碼片段。所以我有兩個錯誤合併在一起。 :) – MichaelXanadu