嗨,我很新的數字簽名。我正在驗證數字簽名的XML文件,我已經驗證它使用下面的代碼。但我想知道它是如何驗證XML是否正確或被篡改。在閱讀一些文章後,我發現 1.爲XML創建散列(不包括簽名部分) 2.使用公鑰解密簽名(您將獲得散列值) 3.比較兩個散列。 (如果兩個哈希匹配,那麼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#rsa-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>u+1NVN5c3gbaxmIrkO9SzVQDklA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>QtQJjevrggzsFZj7PqD3p7GaWkzJAfyacjbMgMXgszCuO+Pxe2rrkScqvgGt2DJqgVlTbC/m9gnodCu7BcXSmW459mSJtyGH+ekWwj6g9ej8I7IYWCRqbI5uus3r3+vr/8ECd5CP/khu/LcCMyPuNIxA8h2EywCeQgbXBvLiWcdexBazdKQQpFxlKw0i+oTs8Ou6jViOdX1ZmTRtdKCQXzAElvpyNimQSmO9OECEs/TytjzIG98mpldfdofoq/2JC+xQhs6IF+Ctw/zlJdkgj1U18U/00Cw4puT4oScTELNSihSS+i9gAL+YjZLlIeunACbnZ4B1CVL/uS9kLlutXQ==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>kHORMZQYOifL5UdIhKe54SfvJKyzLL5Aaw9MgpzeQPgBMmD9KMRnkeU+5RYMiUW8GT3q4eW77UihyxSX3MTAHzuqXoc6GjkBO1Tr41isud721SG7iMspw829YZKAHAPDAl0BV5gpLZagH8KXrDp4dVU+XDOOLZZZWZnbpKSFKvLaJO34KphZ/9W3L/l1BOwEs7132svmtwGgPO2Y16C90sDRWp78ZCYYhb7fAez7683+fijZCDGuVTvS0lBKhmH0ETiNfBAiELUUwHvQ5GHOFSp5PA8+hV9F7zxno1a0/OBpRsHfLydm3THyMUS7DlPE46zPiO9rRIUe90aQ64ulYQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
和簽名部分的我是多麼驗證XML:
private void btnVerifySign_Click(object sender, EventArgs e)
{
string LModulus = node.SelectSingleNode("//Signature/KeyInfo/KeyValue/RSAKeyValue/Modulus").InnerText.ToString();
string LExponent = node.SelectSingleNode("//Signature/KeyInfo/KeyValue/RSAKeyValue/Exponent").InnerText.ToString();
using (var rsa = new RSACryptoServiceProvider())
{
var rsaParam = new RSAParameters()
{
Modulus = Convert.FromBase64String(LModulus),
Exponent = Convert.FromBase64String(LExponent)
};
rsa.ImportParameters(rsaParam);
bool result = VerifyXml(newxml1, rsa);
}
public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
{
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
if (Key == null)
throw new ArgumentException("Key");
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(Doc);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
// throw new CryptographicException("Verification failed: No Signature was found in the document.");
MessageBox.Show("Verification failed: No Signature was found in the document.");
}
// This example only supports one signature for
// the entire XML document. Throw an exception
// if more than one signature was found.
if (nodeList.Count > 1)
{
MessageBox.Show("Verification failed: More that one signature was found for the document.");
// throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key);
}
這兒如果我修改XML並驗證它通過VerifyXml方法返回false和如果我不修改xml VerifyXml方法返回true。我想知道它是如何驗證XML的?我嘗試過比較nodeList [0]中被篡改和未被篡改的XML的值,並且得到了相同的值,但是簽署了XML.CheckSignature(Key)返回true/false。對於不同的xml,摘要值應該不同?在這裏,我獲得了修改和未修改的xml的相同摘要值。並基於CheckSignature(Key)返回true/false。何時爲XML創建哈希值?謝謝。
但是這裏元素爲空。這是什麼意思?數據對象的散列不會生成? –
Rakesh
@Rakesh在你的例子中''元素不爲null。它包含'',''和''元素。 ''包含數據對象的散列,使用''中定義的算法生成。在RFC 3275的4.3.3節中,據說_Reference是可能發生一次或多次的元素。您也可以在該部分找到''元素內容的描述。 –
Nikemundo