Share via


HOW TO:驗證 XML 文件的數位簽章

您可以使用 System.Security.Cryptography.Xml 命名空間中的類別,驗證以數位簽章簽署的 XML 資料。 XML 數位簽章 (XMLDSIG) 可讓您確保資料在簽署之後並未遭到修改。 如需 XMLDSIG 標準的詳細資訊,請參閱全球資訊網協會 (W3C) 的規格,網址為 http://www.w3.org/TR/xmldsig-core/。

這個程序中的程式碼範例會示範如何驗證 <Signature> 項目所包含的 XML 數位簽章。 此範例會從金鑰容器中擷取 RSA 公開金鑰 (Public Key),再使用這個金鑰驗證簽章。

如需有關如何建立可以利用此技巧加以驗證之數位簽章的詳細資訊,請參閱 HOW TO:使用數位簽章簽署 XML 文件

若要驗證 XML 文件的數位簽章

  1. 若要驗證文件,您必須使用與簽署時所用相同的非對稱金鑰。 建立 CspParameters 物件,並指定簽署時所用之金鑰容器的名稱。

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
  2. 使用 RSACryptoServiceProvider 類別擷取公開金鑰。 當您將 CspParameters 物件傳遞至 RSACryptoServiceProvider 類別的建構函式 (Constructor) 時,金鑰便會依名稱自動從金鑰容器載入。

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. 從磁碟載入 XML 檔案,建立 XmlDocument 物件。 XmlDocument 物件含有要驗證的簽署 XML 文件。

    Dim xmlDoc As New XmlDocument()
    
    ' Load an XML file into the XmlDocument object.
    xmlDoc.PreserveWhitespace = True
    xmlDoc.Load("test.xml")
    
    XmlDocument xmlDoc = new XmlDocument();
    
    // Load an XML file into the XmlDocument object.
    xmlDoc.PreserveWhitespace = true;
    xmlDoc.Load("test.xml");
    
  4. 建立新的 SignedXml 物件,並將 XmlDocument 物件傳遞給它。

    Dim signedXml As New SignedXml(Doc)
    
    SignedXml signedXml = new SignedXml(Doc);
    
  5. 找出 <signature> 項目,並建立新的 XmlNodeList 物件。

    Dim nodeList As XmlNodeList = Doc.GetElementsByTagName("Signature")
    
    XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
    
  6. 將第一個 <signature> 項目的 XML 載入至 SignedXml 物件。

    signedXml.LoadXml(CType(nodeList(0), XmlElement))
    
    signedXml.LoadXml((XmlElement)nodeList[0]);
    
  7. 使用 CheckSignature 方法和 RSA 公開金鑰檢查簽章。 這個方法會傳回指示成功或失敗的布林 (Boolean) 值。

    Return signedXml.CheckSignature(Key)
    
    return signedXml.CheckSignature(Key);
    

範例

Imports System
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Xml



Module VerifyXML


    Sub Main(ByVal args() As String)
        Try
            ' Create a new CspParameters object to specify
            ' a key container.
            Dim cspParams As New CspParameters()
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
            ' Create a new RSA signing key and save it in the container. 
            Dim rsaKey As New RSACryptoServiceProvider(cspParams)
            ' Create a new XML document.
            Dim xmlDoc As New XmlDocument()

            ' Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")
            ' Verify the signature of the signed XML.
            Console.WriteLine("Verifying signature...")
            Dim result As Boolean = VerifyXml(xmlDoc, rsaKey)

            ' Display the results of the signature verification to 
            ' the console.
            If result Then
                Console.WriteLine("The XML signature is valid.")
            Else
                Console.WriteLine("The XML signature is not valid.")
            End If

        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

    End Sub





    ' Verify the signature of an XML file against an asymmetric 
    ' algorithm and return the result.
    Function VerifyXml(ByVal Doc As XmlDocument, ByVal Key As RSA) As [Boolean]
        ' Check arguments.
        If Doc Is Nothing Then
            Throw New ArgumentException("Doc")
        End If
        If Key Is Nothing Then
            Throw New ArgumentException("Key")
        End If
        ' Create a new SignedXml object and pass it
        ' the XML document class.
        Dim signedXml As New SignedXml(Doc)
        ' Find the "Signature" node and create a new
        ' XmlNodeList object.
        Dim nodeList As XmlNodeList = Doc.GetElementsByTagName("Signature")
        ' Throw an exception if no signature was found.
        If nodeList.Count <= 0 Then
            Throw New CryptographicException("Verification failed: No Signature was found in the document.")
        End If

        ' This example only supports one signature for
        ' the entire XML document.  Throw an exception 
        ' if more than one signature was found.
        If nodeList.Count >= 2 Then
            Throw New CryptographicException("Verification failed: More that one signature was found for the document.")
        End If

        ' Load the first <signature> node.  
        signedXml.LoadXml(CType(nodeList(0), XmlElement))
        ' Check the signature and return the result.
        Return signedXml.CheckSignature(Key)
    End Function
End Module
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

public class VerifyXML
{

    public static void Main(String[] args)
    {
        try
        {
            // Create a new CspParameters object to specify
            // a key container.
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

            // Create a new RSA signing key and save it in the container. 
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

            // Create a new XML document.
            XmlDocument xmlDoc = new XmlDocument();

            // Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");

            // Verify the signature of the signed XML.
            Console.WriteLine("Verifying signature...");
            bool result = VerifyXml(xmlDoc, rsaKey);

            // Display the results of the signature verification to 
            // the console.
            if (result)
            {
                Console.WriteLine("The XML signature is valid.");
            }
            else
            {
                Console.WriteLine("The XML signature is not valid.");
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }




    // Verify the signature of an XML file against an asymmetric 
    // algorithm and return the result.
    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.");
        }

        // This example only supports one signature for
        // the entire XML document.  Throw an exception 
        // if more than one signature was found.
        if (nodeList.Count >= 2)
        {
            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);
    }
}

這個範例假設,在已編譯程式的相同目錄中,有名為 "test.xml" 的檔案。 "test.xml" 檔案必須使用 HOW TO:使用數位簽章簽署 XML 文件 中所描述的技巧加以簽署。

編譯程式碼

安全性

請勿以純文字格式儲存或傳輸非對稱金鑰組的私密金鑰。 如需對稱和非對稱密碼編譯金鑰的詳細資訊,請參閱產生加密和解密金鑰

請勿直接將私密金鑰嵌入原始程式碼內。 使用 Ildasm.exe (MSIL 反組譯工具) 或在文字編輯器 (例如記事本) 中開啟組件,可以輕易從組件讀取內嵌金鑰。

請參閱

工作

HOW TO:使用數位簽章簽署 XML 文件

參考

System.Security.Cryptography.Xml

其他資源

XML 加密和數位簽章