Condividi tramite


Procedura: verificare le firme digitali dei documenti XML

È possibile utilizzare le classi dello spazio dei nomi System.Security.Cryptography.Xml per verificare i dati XML su cui è stata apposta una firma digitale. Le firme digitali XML (XMLDSIG) consentono di verificare che i dati non siano stati modificati dopo la firma. Per ulteriori informazioni sullo standard XMLDSIG, vedere la specifica W3C (World Wide Web Consortium) all'indirizzo http://www.w3.org/TR/xmldsig-core/ (informazioni in lingua inglese).

Nell'esempio di codice riportato in questa procedura viene illustrato come verificare una firma digitale XML contenuta in un elemento <Signature>. Una chiave pubblica RSA viene recuperata da un contenitore di chiavi e quindi utilizzata per verificare la firma.

Per informazioni sulla creazione di una firma digitale verificabile mediante questa tecnica, vedere Procedura: firmare documenti XML con firme digitali.

Per verificare la firma digitale di un documento XML

  1. Per verificare il documento, è necessario utilizzare la stessa chiave asimmetrica utilizzata per la firma. Creare un oggetto CspParameters e specificare il nome del contenitore di chiavi utilizzato per la firma.

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
  2. Recuperare la chiave pubblica utilizzando la classe RSACryptoServiceProvider. La chiave viene caricata automaticamente dal contenitore di chiavi in base al nome quando si passa l'oggetto CspParameters al costruttore della classe RSACryptoServiceProvider.

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. Creare un oggetto XmlDocument caricando un file XML dal disco. L'oggetto XmlDocument contiene il documento XML firmato da verificare.

    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. Creare un nuovo oggetto SignedXml a cui passare l'oggetto XmlDocument.

    Dim signedXml As New SignedXml(Doc)
    
    SignedXml signedXml = new SignedXml(Doc);
    
  5. Trovare l'elemento <signature> e creare un nuovo oggetto XmlNodeList.

    Dim nodeList As XmlNodeList = Doc.GetElementsByTagName("Signature")
    
    XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
    
  6. Caricare i dati XML del primo elemento <signature> nell'oggetto SignedXml.

    signedXml.LoadXml(CType(nodeList(0), XmlElement))
    
    signedXml.LoadXml((XmlElement)nodeList[0]);
    
  7. Controllare la firma utilizzando il metodo CheckSignature e la chiave pubblica RSA. Questo metodo restituisce un valore booleano che indica l'esito positivo o negativo.

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

Esempio

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);
    }
}

In questo esempio si presuppone che un file denominato "test.xml" si trovi nella stessa directory del programma compilato. Il file "test.xml" deve essere firmato utilizzando le tecniche descritte in Procedura: firmare documenti XML con firme digitali.

Compilazione del codice

Sicurezza

Non memorizzare né trasferire mai la chiave privata di una coppia di chiavi asimmetriche in testo non crittografato. Per ulteriori informazioni sulle chiavi di crittografia simmetriche e asimmetriche, vedere Generazione di chiavi per crittografia e decrittografia.

Non incorporare mai una chiave privata direttamente nel codice sorgente. Le chiavi incorporate possono essere facilmente lette da un assembly attraverso lo strumento Ildasm.exe (disassemblatore MSIL) o aprendo l'assembly in un editor di testo quale Blocco note.

Vedere anche

Attività

Procedura: firmare documenti XML con firme digitali

Riferimenti

System.Security.Cryptography.Xml

Altre risorse

Crittografia XML e firme digitali