Procedura: decrittografare gli elementi XML con chiavi asimmetriche

È possibile usare 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 consente di scambiare o archiviare dati XML crittografati in modo standard, garantendo un'adeguata protezione dei dati da letture non autorizzate. Per ulteriori informazioni sullo standard di crittografia XML, vedere la raccomandazione del World Wide Web Consortium (W3C) relativa a elaborazione e sintassi della firma XML.

Nota

Il codice in questo articolo fa riferimento a Windows.

L'esempio in questa procedura decrittografa un elemento XML crittografato mediante i metodi illustrati in Procedura: Crittografare gli elementi XML con chiavi asimmetriche. Trova un elemento <EncryptedData>, lo decrittografa e quindi lo sostituisce con l'elemento XML originale in testo non crittografato.

Questo esempio decrittografa un elemento XML mediante due chiavi. Recupera una chiave privata RSA generata in precedenza da un contenitore di chiavi e quindi usa la chiave RSA per decrittografare una chiave di sessione archiviata nell'elemento <EncryptedKey> dell'elemento <EncryptedData>. L'esempio usa quindi la chiave di sessione per decrittografare l'elemento XML.

Questo esempio è adatto per situazioni in cui più applicazioni devono condividere dati crittografati o in cui un'applicazione deve salvare 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.

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

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

    // Create a new EncryptedXml object.
    EncryptedXml exml = new EncryptedXml(Doc);
    
    ' Create a new EncryptedXml object.
    Dim exml As New EncryptedXml(Doc)
    
  4. Aggiungere un mapping di chiave/nome per associare la chiave RSA all'elemento entro il documento da decrittografare. È necessario usare per la chiave lo stesso nome specificato durante la crittografia del documento. Si noti che questo nome è distinto dal nome usato per identificare la chiave nel contenitore di chiavi specificato nel passaggio 1.

    exml.AddKeyNameMapping(KeyName, Alg);
    
    exml.AddKeyNameMapping(KeyName, Alg)
    
  5. Chiamare il metodo DecryptDocument per decrittografare l'elemento <EncryptedData>. Questo metodo usa la chiave RSA per decrittografare la chiave di sessione e usa automaticamente la chiave di sessione per decrittografare l'elemento XML. Sostituisce anche automaticamente l'elemento <EncryptedData> con il testo non crittografato originale.

    exml.DecryptDocument();
    
    exml.DecryptDocument()
    
  6. Salvare il documento XML.

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

Esempio

Questo esempio presuppone che sia presente un file denominato test.xml nella stessa directory del programma compilato Presuppone inoltre che test.xml contenga un elemento XML crittografato usando le tecniche descritte in Procedura: Crittografare gli elementi XML con chiavi asimmetriche.


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

[SupportedOSPlatform("windows")]
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();
    }
}
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.  
        ArgumentNullException.ThrowIfNull(Doc)
        ArgumentNullException.ThrowIfNull(Alg)
        ArgumentNullException.ThrowIfNull(KeyName)

        ' 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

Compilazione del codice

Sicurezza .NET

Non archiviare mai una chiave crittografica in testo non crittografato e non trasferire mai in testo non crittografato una chiave simmetrica tra computer. Non archiviare né trasferire mai in testo non crittografato, inoltre, la chiave privata di una coppia di chiavi asimmetriche. Per altre informazioni sulle chiavi crittografiche 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 lette facilmente da un assembly mediante Ildasm.exe (IL Disassembler) oppure aprendo l'assembly in un editor di testo quale Blocco note.

Dopo avere usato una chiave crittografica, cancellarla dalla memoria impostando ogni byte su zero oppure chiamando il metodo Clear della classe di crittografia gestita. Le chiavi crittografiche possono essere a volte lette dalla memoria da un debugger oppure possono essere lette da un disco rigido, se viene eseguito il paging su disco della posizione di memoria.

Vedi anche