Cara: Memverifikasi Tanda Tangan Digital Dokumen XML

Anda dapat menggunakan kelas pada System.Security.Cryptography.Xml namespace layanan untuk memverifikasi data XML yang ditandatangani dengan tanda tangan digital. Tanda tangan digital XML (XMLDSIG) memungkinkan Anda memverifikasi bahwa data tidak diubah setelah ditandatangani. Untuk informasi selengkapnya tentang standar XMLDSIG, lihat spesifikasi World Wide Web Consortium (W3C) pada https://www.w3.org/TR/xmldsig-core/.

Catatan

Kode ini berlaku untuk Windows.

Contoh kode dalam prosedur ini menunjukkan cara memverifikasi tanda tangan digital XML yang terkandung dalam elemen <Signature>. Contoh tersebut mengambil kunci umum RSA dari kontainer kunci lalu menggunakan kunci tersebut untuk memverifikasi tanda tangan.

Untuk informasi tentang cara membuat tanda tangan digital yang dapat diverifikasi menggunakan teknik ini, lihat Panduan: Menandatangani Dokumen XML dengan Tanda Tangan Digital.

Untuk memverifikasi tanda tangan digital dokumen XML

  1. Untuk memverifikasi dokumen, Anda harus menggunakan kunci asimetris yang sama yang digunakan untuk penandatanganan. Buat sebuah CspParameters objek dan tentukan nama kontainer kunci yang digunakan untuk penandatanganan.

    CspParameters cspParams = new()
    {
        KeyContainerName = "XML_DSIG_RSA_KEY"
    };
    
    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
  2. Ambil kunci umum menggunakan RSACryptoServiceProvider kelas. Kunci secara otomatis disimpan ke kontainer kunci saat Anda meneruskan objek CspParameters ke konstruktor kelas RSACryptoServiceProvider.

    RSACryptoServiceProvider rsaKey = new(cspParams);
    
    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
  3. Buat sebuah objek XmlDocument dengan memuat file XML dari disk. Objek XmlDocument berisi dokumen XML yang ditandatangani untuk diverifikasi.

    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. Buat objek SignedXml yang baru dan teruskan objek XmlDocument tersebut ke objek baru itu.

    SignedXml signedXml = new(xmlDoc);
    
    Dim signedXml As New SignedXml(xmlDoc)
    
  5. Temukan elemen <signature> dan buatlah objek XmlNodeList yang baru.

    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
    
    Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
    
  6. Muat XML dari elemen <signature> pertama ke dalam objek SignedXml.

    signedXml.LoadXml((XmlElement?)nodeList[0]);
    
    signedXml.LoadXml(CType(nodeList(0), XmlElement))
    
  7. Periksa tanda tangan menggunakan CheckSignature metode dan kunci umum RSA. Metode ini mengembalikan nilai Boolean yang menunjukkan keberhasilan atau kegagalan.

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

Contoh

Contoh ini mengasumsikan bahwa file yang bernama "test.xml" berada dalam direktori yang sama dengan program yang dikompilasi. File "test.xml" harus ditandatangani menggunakan teknik yang dijelaskan dalam Panduan: Menandatangani Dokumen XML dengan Tanda Tangan Digital.

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

Mengompilasi Kode

.NET Keamanan

Jangan pernah menyimpan atau mentransfer kunci privat dari pasangan kunci asimetris dalam teks biasa. Untuk informasi selengkapnya tentang kunci kriptografi simetris dan asimetris, lihat Membuat Kunci untuk Enkripsi dan Dekripsi.

Jangan pernah menyematkan kunci langsung ke dalam kode sumber Anda. Kunci yang disematkan dapat dengan mudah dibaca dari perakitan menggunakan Ildasm.exe (IL Disassembler) atau dengan membuka rakitan di editor teks seperti Notepad.

Lihat juga