Compartir a través de


Cómo: Descifrar elementos XML con claves asimétricas

Actualización: noviembre 2007

Puede utilizar las clases del espacio de nombres System.Security.Cryptography.Xml para cifrar y descifrar un elemento dentro de un documento XML. El cifrado XML es un medio estándar de intercambiar o almacenar datos XML cifrados, sin preocuparse de que pudiera resultar fácil leer los datos. Para obtener más información sobre el estándar de cifrado XML, vea la especificación de World Wide Web Consortium (W3C) acerca del cifrado XML en http://www.w3.org/TR/xmldsig-core/.

En el ejemplo de este procedimiento se descifra un elemento XML que se cifró según los métodos descritos en: Cómo: Cifrar elementos XML con claves asimétricas. Se busca un elemento <EncryptedData>, se descifra y después se reemplaza con el elemento XML original de texto sin formato.

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

Este ejemplo resulta adecuado para situaciones en las que varias aplicaciones tienen que compartir datos cifrados o cuando una aplicación debe guardar datos cifrados entre períodos de ejecución.

Para descifrar un elemento XML con una clave asimétrica

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

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

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
         RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. Cree un nuevo objeto EncryptedXml para descifrar el 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. Agregue una asignación de clave/nombre para asociar la clave RSA al elemento dentro del documento que se debería descifrar. Debe utilizar para la clave el mismo nombre que utilizó cuando cifró el documento. Tenga en cuenta que este nombre es independiente del nombre utilizado para identificar la clave en el contenedor de claves especificado en el paso 1.

    ' Create a new EncryptedXml object.
    Dim exml As New EncryptedXml(Doc)
    
         // Create a new EncryptedXml object.
            EncryptedXml exml = new EncryptedXml(Doc);
    
  5. Llame al método DecryptDocument para descifrar el elemento <EncryptedData>. Este método utiliza la clave RSA para descifrar la clave de sesión y utiliza la clave de sesión automáticamente para descifrar el elemento XML. También reemplaza automáticamente el elemento <EncryptedData> con el texto sin formato original.

    exml.AddKeyNameMapping(KeyName, Alg)
    
         exml.AddKeyNameMapping(KeyName, Alg);
    
  6. Guarde el documento XML.

    exml.DecryptDocument()
    
         exml.DecryptDocument();
    

Ejemplo

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

    }

}

En este ejemplo se supone que existe un archivo llamado "test.xml" 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.

Compilar el código

Seguridad

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

No incruste nunca una clave directamente en el código fuente. Las claves incrustadas se pueden leer con facilidad de un ensamblado mediante Desensamblador de MSIL (Ildasm.exe) o abriendo el ensamblado con un editor de texto como Bloc de notas.

Cuando haya terminado de usar una clave criptográfica, bórrela de la memoria; para ello, establezca todos los bytes en cero o llame al método Clear de la clase de criptografía administrada. En ocasiones, las claves criptográficas pueden ser leídas de la memoria por un depurador, o bien de una unidad de disco duro si la ubicación de la memoria se pagina en el disco.

Vea también

Tareas

Cómo: Cifrar elementos XML con claves asimétricas

Referencia

System.Security.Cryptography.Xml

Otros recursos

Cifrado XML y firmas digitales