Procedura: decrittografare gli elementi XML con chiavi asimmetriche

Aggiornamento: novembre 2007

È possibile utilizzare le classi dello spazio dei nomi System.Security.Cryptography.Xml per crittografare e decrittografare un elemento all'interno di un documento XML. La crittografia XML è un sistema standard per lo scambio o la memorizzazione di dati XML crittografati che garantisce un'adeguata protezione da letture non autorizzate. Per ulteriori informazioni sulla crittografia XML, vedere la specifica W3C (World Wide Web Consortium) relativa a questo standard all'indirizzo http://www.w3.org/TR/xmldsig-core/ (informazioni in lingua inglese).

Nell'esempio riportato in questa procedura viene decrittografato un elemento XML che è stato crittografato utilizzando i metodi descritti in Procedura: crittografare gli elementi XML con chiavi asimmetriche. Un elemento <EncryptedData> viene trovato, decrittografato e sostituito con l'elemento XML originale in testo non crittografato.

Nell'esempio un elemento XML viene decrittografato mediante due chiavi. Una chiave privata RSA generata in precedenza viene recuperata da un contenitore di chiavi, quindi utilizzata per decrittografare una chiave di sessione memorizzata nell'elemento <EncryptedKey> dell'elemento <EncryptedData>. Viene quindi utilizzata la chiave di sessione per decrittografare l'elemento XML.

Questo esempio si riferisce alle situazioni in cui più applicazioni devono condividere dati crittografati o un'applicazione deve salvare i dati crittografati tra un'esecuzione e l'altra.

Per decrittografare un elemento XML con una chiave asimmetrica

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

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
    
         CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
    
  2. Recuperare una chiave asimmetrica generata in precedenza dal contenitore utilizzando l'oggetto RSACryptoServiceProvider. La chiave viene recuperata automaticamente dal contenitore di chiavi quando si passa l'oggetto CspParameters al costruttore del costruttore RSACryptoServiceProvider.

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
         RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. Creare un nuovo oggetto EncryptedXml per decrittografare il documento.

    Dim xmlDoc As New XmlDocument()
    
    ' Load an XML file into the XmlDocument object.
    Try
        xmlDoc.PreserveWhitespace = True
        xmlDoc.Load("test.xml")
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try
    
         XmlDocument xmlDoc = new XmlDocument();
    
            // Load an XML file into the XmlDocument object.
            try
            {
                xmlDoc.PreserveWhitespace = true;
                xmlDoc.Load("test.xml");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
    
  4. Aggiungere un mapping chiave/nome per associare la chiave RSA all'elemento all'interno del documento da decrittografare. È necessario utilizzare per la chiave lo stesso nome utilizzato al momento della crittografia del documento. Questo nome è distinto da quello utilizzato per identificare la chiave nel contenitore di chiavi specificata nel passaggio 1.

    ' Create a new EncryptedXml object.
    Dim exml As New EncryptedXml(Doc)
    
         // Create a new EncryptedXml object.
            EncryptedXml exml = new EncryptedXml(Doc);
    
  5. Chiamare il metodo DecryptDocument per decrittografare l'elemento <EncryptedData>. Tale metodo utilizza la chiave RSA per decrittografare la chiave di sessione, che viene utilizzata automaticamente per decrittografare a sua volta l'elemento XML. Sostituisce inoltre automaticamente l'elemento <EncryptedData> con il testo non crittografato originale.

    exml.AddKeyNameMapping(KeyName, Alg)
    
         exml.AddKeyNameMapping(KeyName, Alg);
    
  6. Salvare il documento XML.

    exml.DecryptDocument()
    
         exml.DecryptDocument();
    

Esempio

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



Module Program

    Sub Main(ByVal args() As String)

        ' Create an XmlDocument object.
        Dim xmlDoc As New XmlDocument()

        ' Load an XML file into the XmlDocument object.
        Try
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try
        Dim cspParams As New CspParameters()
        cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
        ' Get the RSA key from the key container.  This key will decrypt 
        ' a symmetric key that was imbedded in the XML document. 
        Dim rsaKey As New RSACryptoServiceProvider(cspParams)
        Try

            ' Decrypt the elements.
            Decrypt(xmlDoc, rsaKey, "rsaKey")

            ' Save the XML document.
            xmlDoc.Save("test.xml")
            ' Display the encrypted XML to the console.
            Console.WriteLine()
            Console.WriteLine("Decrypted XML:")
            Console.WriteLine()
            Console.WriteLine(xmlDoc.OuterXml)
        Catch e As Exception
            Console.WriteLine(e.Message)
        Finally
            ' Clear the RSA key.
            rsaKey.Clear()
        End Try


        Console.ReadLine()

    End Sub



    Sub Decrypt(ByVal Doc As XmlDocument, ByVal Alg As RSA, ByVal KeyName As String)
        ' Check the arguments.  
        If Doc Is Nothing Then
            Throw New ArgumentNullException("Doc")
        End If
        If Alg Is Nothing Then
            Throw New ArgumentNullException("Alg")
        End If
        If KeyName Is Nothing Then
            Throw New ArgumentNullException("KeyName")
        End If 
        ' Create a new EncryptedXml object.
        Dim exml As New EncryptedXml(Doc)
        ' Add a key-name mapping.
        ' This method can only decrypt documents
        ' that present the specified key name.
        exml.AddKeyNameMapping(KeyName, Alg)
        ' Decrypt the element.
        exml.DecryptDocument()
    End Sub
End Module

using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

class Program
{
    static void Main(string[] args)
    {

        // Create an XmlDocument object.
        XmlDocument xmlDoc = new XmlDocument();

        // Load an XML file into the XmlDocument object.
        try
        {
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_ENC_RSA_KEY";

        // Get the RSA key from the key container.  This key will decrypt
        // a symmetric key that was imbedded in the XML document.
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

        try
        {

            // Decrypt the elements.
            Decrypt(xmlDoc, rsaKey, "rsaKey");

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

            // Display the encrypted XML to the console.
            Console.WriteLine();
            Console.WriteLine("Decrypted XML:");
            Console.WriteLine();
            Console.WriteLine(xmlDoc.OuterXml);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            // Clear the RSA key.
            rsaKey.Clear();
        }


        Console.ReadLine();


    }

    public static void Decrypt(XmlDocument Doc, RSA Alg, string KeyName)
    {
        // Check the arguments.
        if (Doc == null)
            throw new ArgumentNullException("Doc");
        if (Alg == null)
            throw new ArgumentNullException("Alg");
        if (KeyName == null)
            throw new ArgumentNullException("KeyName");
        // Create a new EncryptedXml object.
        EncryptedXml exml = new EncryptedXml(Doc);

        // Add a key-name mapping.
        // This method can only decrypt documents
        // that present the specified key name.
        exml.AddKeyNameMapping(KeyName, Alg);

        // Decrypt the element.
        exml.DecryptDocument();

    }

}

In questo esempio si presuppone che un file denominato "test.xml" si trovi nella stessa directory del programma compilato e che contenga un elemento XML crittografato mediante le tecniche illustrate in Procedura: crittografare gli elementi XML con chiavi asimmetriche.

Compilazione del codice

Sicurezza

Non memorizzare mai una chiave di crittografia simmetrica né trasferire una chiave simmetrica da un computer all'altro in testo non crittografato. Inoltre, 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 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.

Dopo aver utilizzato una chiave di crittografia, cancellarla dalla memoria impostando ogni byte su zero o chiamando il metodo Clear della classe di crittografia gestita. Le chiavi di crittografia possono talvolta essere lette dalla memoria mediante un debugger o da un disco rigido se la posizione della memoria è paginata su disco.

Vedere anche

Attività

Procedura: crittografare gli elementi XML con chiavi asimmetriche

Riferimenti

System.Security.Cryptography.Xml

Altre risorse

Crittografia XML e firme digitali