Procedimiento para descifrar elementos XML con claves asimétricas

Puede usar las clases en el espacio de nombres System.Security.Cryptography.Xml para cifrar y descifrar un elemento dentro de un documento XML. El cifrado XML es un método estándar para intercambiar o almacenar datos XML cifrados sin preocuparse de que los datos puedan leerse con facilidad. Para más información sobre el estándar de cifrado XML, consulte la recomendación de World Wide Web Consortium (W3C) sobre procesamiento y sintaxis de firma de XML.

Nota

El código de este artículo se aplica a Windows.

En el ejemplo de este procedimiento se descifra un elemento XML cifrado mediante los métodos descritos en Cifrado de elementos XML con claves asimétricas. Busca un elemento <EncryptedData>, lo descifra y lo reemplaza por el elemento XML de texto sin formato original.

En este ejemplo se descifra un elemento XML mediante dos claves. Recupera una clave privada RSA generada anteriormente de un contenedor de claves y la usa para descifrar una clave de sesión almacenada en el elemento <EncryptedKey> del elemento <EncryptedData>. Luego, el ejemplo usa la clave de sesión para descifrar el elemento XML.

Este ejemplo resulta adecuado en aquellas situaciones en las que varias aplicaciones tienen que compartir datos cifrados o en las que una aplicación tiene que guardar datos cifrados entre los intervalos en los que se ejecuta.

Para descifrar un elemento XML con una clave asimétrica

  1. Cree un objeto CspParameters y especifique el nombre del contenedor de claves.

    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
    
    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
    
  2. Recupere una clave asimétrica previamente generada desde el contenedor mediante el objeto RSACryptoServiceProvider. La clave se recupera automáticamente del contenedor de claves al pasar el objeto CspParameters al constructor RSACryptoServiceProvider.

    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
  3. Cree un objeto EncryptedXml nuevo para descifrar el documento.

    // Create a new EncryptedXml object.
    EncryptedXml exml = new EncryptedXml(Doc);
    
    ' Create a new EncryptedXml object.
    Dim exml As New EncryptedXml(Doc)
    
  4. Agregue una asignación de clave/nombre para asociar la clave RSA al elemento del documento que se debe descifrar. Debe usar el mismo nombre para la clave que usó al cifrar el documento. Tenga en cuenta que este nombre es independiente del que haya usado para identificar la clave en el contenedor de claves especificado en el paso 1.

    exml.AddKeyNameMapping(KeyName, Alg);
    
    exml.AddKeyNameMapping(KeyName, Alg)
    
  5. Llame al método DecryptDocument para descifrar el elemento <EncryptedData>. Este método usa la clave RSA para descifrar la clave de sesión y la usa automáticamente para descifrar el elemento XML. También reemplaza automáticamente el elemento <EncryptedData> por el texto sin formato original.

    exml.DecryptDocument();
    
    exml.DecryptDocument()
    
  6. Guarde el documento XML.

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

Ejemplo

En este ejemplo se supone que un archivo llamado test.xml se encuentra en el mismo directorio que el programa compilado. También se supone que test.xml contiene un elemento XML que se cifró mediante las técnicas descritas en Cómo: Cifrar elementos XML con claves asimétricas.


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

Compilar el código

Seguridad de .NET

No almacene nunca una clave criptográfica simétrica en texto sin formato ni transfiera una clave simétrica entre equipos en texto sin formato. Tampoco debe almacenar ni transferir nunca la clave privada de un par de claves asimétricas en texto sin formato. Para más información sobre claves criptográficas simétricas y asimétricas, consulte Generar claves para cifrado y descifrado.

No inserte nunca una clave directamente en el código fuente. Las claves insertadas se pueden leer fácilmente desde un ensamblado con Ildasm.exe (Desensamblador de IL) o si se abre el ensamblado en un editor de texto, como el Bloc de notas.

Cuando termine de usar una clave criptográfica, bórrela de la memoria estableciendo cada byte en cero o llamando al método Clear de la clase criptográfica administrada. A veces, las claves criptográficas se pueden leer desde la memoria con un depurador o desde un disco duro si la ubicación de memoria se pagina en el disco.

Consulte también