Partilhar via


Como: criptografar elementos XML com certificados X.509

Você pode usar as classes de System.Security.Cryptography.Xml o namespace para criptografar um elemento dentro de um documento XML. Criptografia XML é uma maneira padrão de troca ou armazena os dados criptografados de XML, sem se preocupar sobre os dados que está sendo lidos facilmente. Para obter mais informações sobre o padrão de criptografia XML, consulte que a especificação de World Wide Web Consortium (W3C) para criptografia XML localizado em http://www.w3.org/TR/xmldsig-core/.

Você pode usar a criptografia XML para substituir qualquer elemento XML ou documento com um <EncryptedData> elemento que contém os dados criptografados do XML. O <EncryptedData> elemento pode conter elementos sub que incluem informações sobre as chaves e os processos usados durante a criptografia. Criptografia XML permite que um documento contêm vários elementos criptografados e permite que um elemento a ser criptografado várias vezes. O exemplo de código neste procedimento mostra como criar um <EncryptedData> elemento juntamente com vários outros elementos de sub que você pode usar mais tarde durante a descriptografia.

Este exemplo criptografa um elemento XML usando duas chaves. Ele gera um certificado de x. 509 de teste usando o O Makecert. exe (ferramenta de criação de certificado) e salva o certificado para um armazenamento de certificado. O exemplo programaticamente recupera o certificado e a usa para criptografar um elemento XML usando o Encrypt método. Internamente, o Encrypt método cria uma chave de sessão separada e o usa para criptografar o documento XML. Esse método criptografa a chave de sessão e salva-o junto com o XML criptografado dentro de um novo <EncryptedData> elemento.

Para descriptografar o elemento XML, basta chamar o DecryptDocument método, que automaticamente recupera o certificado x. 509 do armazenamento e executa a descriptografia necessárias. Para obter mais informações sobre como descriptografar um elemento XML que foi criptografado usando este procedimento, consulte Como: Descriptografar os elementos XML com certificados x. 509.

Este exemplo é apropriado para situações em que vários aplicativos precisam compartilhar dados criptografados ou onde um aplicativo precisa salvar os dados criptografados entre as horas que ele é executado.

Para criptografar um elemento XML com um certificado x. 509

  1. Use o O Makecert. exe (ferramenta de criação de certificado) para gerar um certificado x. 509 de teste e colocá-lo no armazenamento de usuário local. Você deve gerar uma chave de troca e você deve fazer com que a chave exportável. Execute o seguinte comando:

    makecert -r -pe -n "CN=XML_ENC_TEST_CERT" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my
    
  2. Criar um X509Store object e inicializá-lo para abrir o armazenamento de usuário atual.

    Dim store As New X509Store(StoreLocation.CurrentUser)
    
    X509Store store = new X509Store(StoreLocation.CurrentUser);
    
  3. Abra o armazenamento no modo somente leitura.

    store.Open(OpenFlags.ReadOnly)
    
    store.Open(OpenFlags.ReadOnly);
    
  4. Inicializar um X509Certificate2Collection com todos os certificados no armazenamento.

    Dim certCollection As X509Certificate2Collection = store.Certificates
    
    X509Certificate2Collection certCollection = store.Certificates;
    
  5. Enumerar os certificados no armazenamento e encontrar o certificado com o nome adequado. Neste exemplo, o certificado é denominado "CN=XML_ENC_TEST_CERT".

    Dim cert As X509Certificate2 = Nothing
    
    ' Loop through each certificate and find the certificate 
    ' with the appropriate name.
    Dim c As X509Certificate2
    For Each c In certCollection
        If c.Subject = "CN=XML_ENC_TEST_CERT" Then
            cert = c
    
            Exit For
        End If
    Next c
    
    X509Certificate2 cert = null;
    
    // Loop through each certificate and find the certificate 
    // with the appropriate name.
    foreach (X509Certificate2 c in certCollection)
    {
        if (c.Subject == "CN=XML_ENC_TEST_CERT")
        {
            cert = c;
    
            break;
        }
    }
    
  6. Feche o armazenamento depois que o certificado está localizado.

    store.Close()
    
    store.Close();
    
  7. Criar um XmlDocument objeto carregando um arquivo XML a partir do disco. O XmlDocument objeto contém o elemento XML para criptografar.

    Dim xmlDoc As New XmlDocument()
    
    XmlDocument xmlDoc = new XmlDocument();
    
  8. Localizar o elemento especificado na XmlDocument de objeto e criar um novo XmlElement o objeto para representar o elemento que você deseja criptografar. Neste exemplo, o "creditcard" elemento está criptografado.

            Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
    
    
    XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
    
  9. Criar uma nova instância de EncryptedXml de classe e usá-la para criptografar o elemento especificado usando o certificado x. 509. O Encrypt método retorna o elemento criptografado como um EncryptedData objeto.

    Dim eXml As New EncryptedXml()
    
    ' Encrypt the element.
    Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
    
    EncryptedXml eXml = new EncryptedXml();
    
    // Encrypt the element.
    EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);
    
  10. Substituir o elemento do original XmlDocument de objeto com o EncryptedData elemento.

    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    
  11. Salve o XmlDocument objeto.

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

Exemplo

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



Module Program

    Sub Main(ByVal args() As String)
        Try
            ' Create an XmlDocument object.
            Dim xmlDoc As New XmlDocument()
            ' Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")

            ' Open the X.509 "Current User" store in read only mode.
            Dim store As New X509Store(StoreLocation.CurrentUser)
            store.Open(OpenFlags.ReadOnly)
            ' Place all certificates in an X509Certificate2Collection object.
            Dim certCollection As X509Certificate2Collection = store.Certificates
            Dim cert As X509Certificate2 = Nothing

            ' Loop through each certificate and find the certificate 
            ' with the appropriate name.
            Dim c As X509Certificate2
            For Each c In certCollection
                If c.Subject = "CN=XML_ENC_TEST_CERT" Then
                    cert = c

                    Exit For
                End If
            Next c
            If cert Is Nothing Then
                Throw New CryptographicException("The X.509 certificate could not be found.")
            End If

            ' Close the store.
            store.Close()
            ' Encrypt the "creditcard" element.
            Encrypt(xmlDoc, "creditcard", cert)

            ' Save the XML document.
            xmlDoc.Save("test.xml")
            ' Display the encrypted XML to the console.
            Console.WriteLine("Encrypted XML:")
            Console.WriteLine()
            Console.WriteLine(xmlDoc.OuterXml)

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

    End Sub 'Main


    Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal Cert As X509Certificate2)
        ' Check the arguments.  
        If Doc Is Nothing Then
            Throw New ArgumentNullException("Doc")
        End If
        If ElementToEncryptName Is Nothing Then
            Throw New ArgumentNullException("ElementToEncrypt")
        End If
        If Cert Is Nothing Then
            Throw New ArgumentNullException("Cert")
        End If
        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' Find the specified element in the XmlDocument
        ' object and create a new XmlElemnt object.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)

        ' Throw an XmlException if the element was not found.
        If elementToEncrypt Is Nothing Then
            Throw New XmlException("The specified element was not found")
        End If

        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' Create a new instance of the EncryptedXml class 
        ' and use it to encrypt the XmlElement with the 
        ' X.509 Certificate.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        Dim eXml As New EncryptedXml()

        ' Encrypt the element.
        Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' Replace the element from the original XmlDocument
        ' object with the EncryptedData element.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    End Sub
End Module
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Security.Cryptography.X509Certificates;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            // Create an XmlDocument object.
            XmlDocument xmlDoc = new XmlDocument();

            // Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");

            // Open the X.509 "Current User" store in read only mode.
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);

            // Place all certificates in an X509Certificate2Collection object.
            X509Certificate2Collection certCollection = store.Certificates;

            X509Certificate2 cert = null;

            // Loop through each certificate and find the certificate 
            // with the appropriate name.
            foreach (X509Certificate2 c in certCollection)
            {
                if (c.Subject == "CN=XML_ENC_TEST_CERT")
                {
                    cert = c;

                    break;
                }
            }

            if (cert == null)
            {
                throw new CryptographicException("The X.509 certificate could not be found.");
            }

            // Close the store.
            store.Close();

            // Encrypt the "creditcard" element.
            Encrypt(xmlDoc, "creditcard", cert);

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

            // Display the encrypted XML to the console.
            Console.WriteLine("Encrypted XML:");
            Console.WriteLine();
            Console.WriteLine(xmlDoc.OuterXml);

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

    }

    public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, X509Certificate2 Cert)
    {
        // Check the arguments.  
        if (Doc == null)
            throw new ArgumentNullException("Doc");
        if (ElementToEncrypt == null)
            throw new ArgumentNullException("ElementToEncrypt");
        if (Cert == null)
            throw new ArgumentNullException("Cert");

        ////////////////////////////////////////////////
        // Find the specified element in the XmlDocument
        // object and create a new XmlElemnt object.
        ////////////////////////////////////////////////

        XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
        // Throw an XmlException if the element was not found.
        if (elementToEncrypt == null)
        {
            throw new XmlException("The specified element was not found");

        }

        //////////////////////////////////////////////////
        // Create a new instance of the EncryptedXml class 
        // and use it to encrypt the XmlElement with the 
        // X.509 Certificate.
        //////////////////////////////////////////////////

        EncryptedXml eXml = new EncryptedXml();

        // Encrypt the element.
        EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);

        ////////////////////////////////////////////////////
        // Replace the element from the original XmlDocument
        // object with the EncryptedData element.
        ////////////////////////////////////////////////////
        EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    }
}

Este exemplo assume que um arquivo chamado "test.xml" existe no mesmo diretório que o programa compilado. Ele também pressupõe que "test.xml" contém um "creditcard" elemento. Você pode colocar o XML a seguir em um arquivo denominado test.xml e usá-lo com este exemplo.

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

Compilando o código

Segurança

O certificado x. 509 usado neste exemplo é apenas a fins de teste. Aplicativos devem usar um certificado x. 509 gerado por uma autoridade de certificação confiável ou usar um certificado gerado pelo servidor de certificado Microsoft Windows.

Consulte também

Tarefas

Como: Descriptografar os elementos XML com certificados x. 509

Referência

System.Security.Cryptography.Xml

Outros recursos

Criptografia XML e assinaturas digitais