Condividi tramite


Procedura: firmare documenti XML con firme digitali

Aggiornamento: novembre 2007

È possibile utilizzare le classi dello spazio dei nomi System.Security.Cryptography.Xml per apporre una firma digitale su un documento XML o su parte di esso. 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 firmare digitalmente un intero documento XML e allegare la firma al documento in un elemento <Signature>. Dopo essere stata creata, una chiave di firma RSA viene aggiunta a un contenitore di chiavi protetto e quindi utilizzata per firmare digitalmente un documento XML. La chiave può quindi essere recuperata per verificare la firma digitale XML o utilizzata per firmare un altro documento XML.

Per ulteriori informazioni su come verificare una firma digitale XML creata mediante questa procedura, vedere Procedura: verificare le firme digitali dei documenti XML.

Per firmare digitalmente un documento XML

  1. Creare un oggetto CspParameters e specificare il nome del contenitore di chiavi.

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
  2. Generare una chiave simmetrica utilizzando la classe RSACryptoServiceProvider. La chiave viene salvata automaticamente nel contenitore di chiavi quando si passa l'oggetto CspParameters al costruttore della classe RSACryptoServiceProvider e viene quindi utilizzata per firmare il documento XML.

    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 l'elemento XML da crittografare.

    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. Aggiungere la chiave RSA di firma all'oggetto SignedXml.

    signedXml.SigningKey = Key
    
    signedXml.SigningKey = Key;
    
  6. Creare un oggetto Reference che indichi cosa firmare. Per firmare l'intero documento, impostare la proprietà Uri su "".

    ' Create a reference to be signed.
    Dim reference As New Reference()
    reference.Uri = ""
    
    // Create a reference to be signed.
    Reference reference = new Reference();
    reference.Uri = "";
    
  7. Aggiungere un oggetto XmlDsigEnvelopedSignatureTransform all'oggetto Reference. Una trasformazione consente al Verifier di rappresentare i dati XML nella stessa modalità utilizzata dal firmatario. Poiché i dati XML possono essere rappresentati in diversi modi, questo passaggio è fondamentale ai fini della verifica.

    Dim env As New XmlDsigEnvelopedSignatureTransform()
    reference.AddTransform(env)
    
    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(env);
    
  8. Aggiungere l'oggetto Reference all'oggetto SignedXml.

    signedXml.AddReference(reference)
    
    signedXml.AddReference(reference);
    
  9. Elaborare la firma chiamando il metodo ComputeSignature.

    signedXml.ComputeSignature()
    
    signedXml.ComputeSignature();
    
  10. Recuperare la rappresentazione XML della firma (un elemento <Signature>) e salvarla in un nuovo oggetto XmlElement.

    Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
    
    XmlElement xmlDigitalSignature = signedXml.GetXml();
    
  11. Accodare l'elemento all'oggetto XmlDocument.

    Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, True))
    
    Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
    
  12. Salvare il documento.

    xmlDoc.Save("test.xml")
    
    xmlDoc.Save("test.xml");
    

Esempio

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



Module SignXML


    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")
            ' Sign the XML document. 
            SignXml(xmlDoc, rsaKey)

            Console.WriteLine("XML file signed.")

            ' Save the document.
            xmlDoc.Save("test.xml")


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

    End Sub



    ' Sign an XML file. 
    ' This document cannot be verified unless the verifying 
    ' code has the key with which it was signed.
    Sub SignXml(ByVal Doc As XmlDocument, ByVal Key As RSA)
        ' 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 SignedXml object.
        Dim signedXml As New SignedXml(Doc)
        ' Add the key to the SignedXml document.
        signedXml.SigningKey = Key
        ' Create a reference to be signed.
        Dim reference As New Reference()
        reference.Uri = ""
        ' Add an enveloped transformation to the reference.
        Dim env As New XmlDsigEnvelopedSignatureTransform()
        reference.AddTransform(env)
        ' Add the reference to the SignedXml object.
        signedXml.AddReference(reference)
        ' Compute the signature.
        signedXml.ComputeSignature()
        ' Get the XML representation of the signature and save
        ' it to an XmlElement object.
        Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
        ' Append the element to the XML document.
        Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, True))
    End Sub
End Module
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

public class SignXML
{

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

            // Sign the XML document. 
            SignXml(xmlDoc, rsaKey);

            Console.WriteLine("XML file signed.");

            // Save the document.
            xmlDoc.Save("test.xml");



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


    // Sign an XML file. 
    // This document cannot be verified unless the verifying 
    // code has the key with which it was signed.
    public static void SignXml(XmlDocument Doc, RSA Key)
    {
        // Check arguments.
        if (Doc == null)
            throw new ArgumentException("Doc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(Doc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = Key;

        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "";

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);

        // Add the reference to the SignedXml object.
        signedXml.AddReference(reference);

        // Compute the signature.
        signedXml.ComputeSignature();

        // Get the XML representation of the signature and save
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        // Append the element to the XML document.
        Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));

    }
}

In questo esempio si presuppone che un file denominato "test.xml" si trovi nella stessa directory del programma compilato. È possibile inserire i dati XML riportati di seguito in un file denominato test.xml e utilizzarlo con questo esempio.

<root>
    <creditcard>
        <number>19834209</number>
        <expiry>02/02/2002</expiry>
    </creditcard>
</root>

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 Disassembler MSIL (Ildasm.exe) o aprendo l'assembly in un editor di testo quale Blocco note.

Vedere anche

Attività

Procedura: verificare le firme digitali dei documenti XML

Riferimenti

System.Security.Cryptography.Xml

Altre risorse

Crittografia XML e firme digitali