簡體   English   中英

如何驗證數字簽名的XML文件?

[英]How to verify Digitally Signed XML File?

嗨,我是Digital Signing的新手。我正在驗證Digitally Signed XML文件,並已使用以下代碼對其進行了驗證。 但是我想知道它如何驗證XML是否正確或被篡改。 看了幾篇文章后,我發現1.為XML創建哈希(不包括簽名部分)2.使用公鑰解密簽名(您將獲得一個哈希值)3.比較兩個哈希。 (如果兩個哈希都匹配,則不會篡改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,則VerifyFile方法返回true。 我想知道它如何驗證XML? 我嘗試比較nodeList [0]中被篡改和未篡改的XML的值,但我得到了相同的值,但signedXml.CheckSignature(Key)返回的是true / false。 不同的xml的摘要值應該不同嗎? 在這里,我為修改和未修改的xml獲取相同的摘要值。 並根據CheckSignature(Key)究竟返回的是真還是假。 以及何時為xml創建哈希值? 謝謝。

實際上,已簽名的是<SignedInfo>元素,而不是數據對象。 數據對象的哈希包含在<SignedInfo>元素的<Reference>元素中。 因此,數據對象也被間接簽名。 驗證簽名時,會將數據對象的哈希值與<Reference>元素中的已簽名數據摘要進行比較。 然后使用公共密鑰檢查<SignedInfo>元素上的簽名。

有關更多信息,您可以閱讀RFC 3275 在這里,您可以找到有關生成和驗證簽名xml的步驟的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM