2017-07-11 1 views
2

自己署名X.509証明書を使用してSHA256でXMLに署名したいとします。私はStackOverflowの中で多くの記事に触発さと、このコードを使用した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部分はこのようになります:あなたは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"が使用されています(ノード "SignatureMethod" & "DigestMethod"を参照)。しかし、SHA256-URLをこれらのノードに記述する必要があります。この仮定は正しいですか?はいの場合、誰もこの問題を解決する方法を知っていますか?私はC#4.6.0を使用します。ただ計算を行いよろしく、 マイケル

+0

書かれたコードは署名を作成しますが、文書には入れません(事前に署名されていますか?)。 'GetXml()'の呼び出しを逃して、そのノードをドキュメントに挿入しています。 – bartonjs

+0

ありがとう、これは私の問題を解決するのに役立ちました。実際には、署名されたXML-Nodeをxmlファイルに追加するのを忘れていました。上の「間違った」署名付きXML部分は、誤って実行された別のコードスニペットからのものです。だから私は2つのミスが合併した。 :) – MichaelXanadu

答えて

1

あなたが成功しsignedXml.ComputeSignature()と呼ばれるが、それはあなたがコンストラクタに渡したXmlDocumentはGetXml()を文書化するだけで何である(文書に署名要素を挿入しません。 sノードは親ノードになります)。

計算されたds:Signature要素を取得するには、signedXml.GetXml()ComputeSignatureの後)に電話して、ドキュメントに挿入する必要があります。

文書に署名ノードが既に含まれているという事実は混乱しています。私の最初の考えは、すでにtest.xmlにその署名がありましたが、あなたのコメントによれば、それは他の場所からのほんの一部のoopsコードでした。レッスンは、私が推測したことを学んだ。

関連する問題