2012-12-06 30 views
4

我試圖在C#中使用SignedXml class簽署Xml(實際上是SOAP xml),簽名階段通過成功,但是當我嘗試驗證簽名時,它告訴我認爲這是無效的。 我從MSDN中的示例中完成的唯一更改,我使用XmlDsigExcC14NTransform而不是XmlDsigEnvelopedSignatureTransform變換。 如果我使用XmlDsigEnvelopedSignatureTransform,我將得到一個有效的簽名。.Net:SignedXml - 用變換算法簽署xml exc -c14n

這裏是我的簽名代碼:

private static XmlDocument SignXml(XmlDocument doc) 
      { 
       SignedXml signedXml = new SignedXml(doc); 
       signedXml.SigningKey = Certificate.PrivateKey; 

       Reference reference = new Reference(); 
       reference.Uri = ""; 

       XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); 
       //XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform(); 

       reference.AddTransform(env); 

       signedXml.AddReference(reference); 
       signedXml.ComputeSignature(); 

       XmlElement signature = signedXml.GetXml(); 
       doc.DocumentElement.AppendChild(signature); 
       doc.Save(SignedXmlPath); 
       return doc; 
      } 

上面的代碼將會給我一個有效的簽名,但如果我使用的

XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); 

XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform(); 

相反,我會得到無效的簽名。

這裏是我的驗證碼:

private static bool Verify(XmlDocument doc) 
     { 
      SignedXml signedDoc = new SignedXml(doc); 
      XmlNodeList nodeList = doc.GetElementsByTagName(Constants.SignatureElement); 

      signedDoc.LoadXml((XmlElement)nodeList[0]); 
      return signedDoc.CheckSignature((RSA)Certificate.PublicKey.Key); 
     } 

誰能告訴我怎麼可以登錄提前變換http://www.w3.org/2001/10/xml-exc-c14n#

由於算法。

回答

8

您需要在您的案例中使用XmlDsigEnvelopedSignatureTransform,因爲您要在簽名的元素內添加簽名。

XmlDsigEnvelopedSignatureTransform會告訴SignedXml類測試它的有效性之前,請從簽名節點本身的簽名。這是需要的,因爲您在計算簽名後添加了該元素。

您可以通過調用AddTransform再這樣加一個以上的變換:

XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); 
XmlDsigExcC14NTransform c14n = new XmlDsigExcC14NTransform(); 

reference.AddTransform(env); 
reference.AddTransform(c14n); 

但是我想你真正想要做的,而不是我上面的例子是什麼設置CanonicalizationMethod到C14N:

signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#"; 
- or - 
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; 
+0

謝謝Jan,您的回答。我現在知道了。 其實我需要在SOAP消息中籤署正文,然後我將簽名添加到SOAP信封中的安全頭。所以如果我這樣做,我將能夠使用XmlDsigExcC14NTransform,因爲那樣Signature元素將不會是已簽名元素的一部分。對? 再次感謝... – Mahmoud

+1

是的,這應該工作得很好。 –

+1

謝謝。我有一個類似的情況,也需要:c14n.Algorithm = SignedXml.XmlDsigExcC14NTransformUrl; – Paul