방법: XML 문서의 디지털 서명 확인

System.Security.Cryptography.Xml 네임스페이스의 클래스를 사용하여 디지털 서명으로 서명된 XML 데이터를 확인할 수 있습니다. XML 디지털 서명(XMLDSIG)을 사용하면 서명된 후 데이터가 변경되지 않았음을 확인할 수 있습니다. XMLDSIG 표준에 대한 자세한 내용은 https://www.w3.org/TR/xmldsig-core/의 W3C(World Wide Web 컨소시엄) 사양을 참조하세요.

참고 항목

이 문서의 코드는 Windows에 적용됩니다.

이 프로시저의 코드 예제에서는 <Signature> 요소에 포함된 XML 디지털 서명을 확인하는 방법에 대해 설명합니다. 이 예제에서는 키 컨테이너에서 RSA 공개 키를 검색한 다음 키를 사용하여 서명을 확인합니다.

이 기술을 사용하여 확인할 수 있는 디지털 서명을 만드는 방법에 대한 자세한 내용은 방법: 디지털 서명으로 XML 문서에 서명을 참조하세요.

XML 문서의 디지털 서명을 확인하려면

  1. 문서를 확인하려면 서명에 사용된 것과 동일한 비대칭 키를 사용해야 합니다. CspParameters 개체를 만들고 서명에 사용된 키 컨테이너의 이름을 지정합니다.

    CspParameters cspParams = new()
    {
        KeyContainerName = "XML_DSIG_RSA_KEY"
    };
    
    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
  2. RSACryptoServiceProvider 클래스를 사용하여 공개 키를 검색합니다. RSACryptoServiceProvider 클래스의 생성자에 CspParameters 개체를 전달하면 키가 이름을 기준으로 자동으로 키 컨테이너에서 로드됩니다.

    RSACryptoServiceProvider rsaKey = new(cspParams);
    
    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
  3. 디스크에서 XML 파일을 로드하여 XmlDocument 개체를 만듭니다. XmlDocument 개체에는 확인할 서명된 XML 문서가 들어 있습니다.

    XmlDocument xmlDoc = new()
    {
        // Load an XML file into the XmlDocument object.
        PreserveWhitespace = true
    };
    xmlDoc.Load("test.xml");
    
    Dim xmlDoc As New XmlDocument()
    
    ' Load an XML file into the XmlDocument object.
    xmlDoc.PreserveWhitespace = True
    xmlDoc.Load("test.xml")
    
  4. SignedXml 개체를 만들고 XmlDocument 개체를 전달합니다.

    SignedXml signedXml = new(xmlDoc);
    
    Dim signedXml As New SignedXml(xmlDoc)
    
  5. <signature> 요소를 찾아 새 XmlNodeList 개체를 만듭니다.

    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
    
    Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
    
  6. 첫 번째 <signature> 요소의 XML을 SignedXml 개체에 로드합니다.

    signedXml.LoadXml((XmlElement?)nodeList[0]);
    
    signedXml.LoadXml(CType(nodeList(0), XmlElement))
    
  7. CheckSignature 메서드 및 RSA 공개 키를 사용하여 서명을 확인합니다. 이 메서드는 성공 또는 실패를 나타내는 부울 값을 반환합니다.

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

예시

이 예제에서는 "test.xml"이라는 파일이 컴파일된 프로그램과 동일한 디렉터리에 있다고 가정합니다. "test.xml" 파일은 방법: 디지털 서명으로 XML 문서 서명에 설명된 기술을 사용하여 서명해야 합니다.

using System;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

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

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

            // Create a new XML document.
            XmlDocument xmlDoc = new()
            {
                // Load an XML file into the XmlDocument object.
                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 bool VerifyXml(XmlDocument xmlDoc, RSA key)
    {
        // Check arguments.
        if (xmlDoc == null)
             throw new ArgumentException(null, nameof(xmlDoc));
        if (key == null)
            throw new ArgumentException(null, nameof(key));

        // Create a new SignedXml object and pass it
        // the XML document class.
        SignedXml signedXml = new(xmlDoc);

        // Find the "Signature" node and create a new
        // XmlNodeList object.
        XmlNodeList nodeList = xmlDoc.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);
    }
}
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 xmlDoc As XmlDocument, ByVal key As RSA) As [Boolean]
        ' Check arguments.
        If xmlDoc Is Nothing Then
            Throw New ArgumentException(
                "The XML doc cannot be nothing.", NameOf(xmlDoc))
        End If
        If key Is Nothing Then
            Throw New ArgumentException(
                "The key cannot be nothing.", NameOf(key))
        End If
        ' Create a new SignedXml object and pass it
        ' the XML document class.
        Dim signedXml As New SignedXml(xmlDoc)
        ' Find the "Signature" node and create a new
        ' XmlNodeList object.
        Dim nodeList As XmlNodeList = xmlDoc.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

코드 컴파일

.NET 보안

비대칭 키 쌍의 프라이빗 키를 일반 텍스트로 저장하거나 전송하지 마세요. 대칭 및 비대칭 암호화 키에 대한 자세한 내용은 암호화 및 암호 해독용 키 생성을 참조하세요.

소스 코드에 직접 프라이빗 키를 포함하지 마세요. 포함된 키는 Ildasm.exe(IL 디스어셈블러)를 사용하거나 메모장과 같은 텍스트 편집기에서 어셈블리를 열어 어셈블리에서 쉽게 읽을 수 있습니다.

참고 항목