Sdílet prostřednictvím


Postupy: Šifrování XML elementů pomocí certifikátů X.509

K zašifrování elementu dokumentu XML lze použít třídy v oboru názvů System.Security.Cryptography.Xml. Šifrování XML představuje standardní způsob pro předávají nebo ukládaní zašifrovaných dat XML bez obav, že by byla data snadno čitelná. Další informace o standardu šifrování XML naleznete ve specifikaci šifrování XML na webových stránkách konsorcia W3C (World Wide Web Consortium) http://www.w3.org/TR/xmldsig-core/.

Pomocí šifrování XML lze nahradit libovolný element XML nebo dokument XML elementem <EncryptedData>, který obsahuje šifrovaná data XML. Element <EncryptedData> může obsahovat dílčí elementy, které obsahují informace o klíčích a postupech použitých při šifrování. Šifrování XML umožňuje, aby dokument obsahoval více šifrovaných elementů a umožňuje, aby byl element zašifrován vícekrát. Příklad kódu v tomto postupu vám ukazuje, jak vytvořit element <EncryptedData> spolu s několika dalšími dílčími elementy, které lze použít později během dešifrování.

V tomto příkladu je šifrován element XML pomocí dvou klíčů. Generuje testovací certifikát X.509 pomocí Makecert.exe (Certificate Creation Tool) a ukládá ho do úložiště certifikátů. V příkladu je potom certifikát programově načten a použit k zašifrování elementu XML pomocí metody Encrypt. Vnitřně metoda Encrypt vytváří oddělený klíč relace a používá ho k šifrování dokumentu XML. Tato metoda zašifruje klíč relace a uloží jej spolu s šifrovanými XML daty do nového elementu <EncryptedData>.

Chcete-li dešifrovat element XML, jednoduše zavolejte metodu DecryptDocument, která automaticky z úložiště načte certifikát X.509 a provede nezbytné dešifrování. Další informace o dešifrování elementu XML, který byl zašifrován pomocí tohoto postupu, naleznete v tématu Postupy: Dešifrovat elementy XML s certifikáty X.509.

Tento příklad je vhodný pro situace, kde je třeba sdílení zašifrovaných dat mezi více aplikacemi nebo pokud aplikace potřebuje uložit zašifrovaná data za běhu.

Šifrování elementu XML pomocí certifikátu X.509

  1. Použijte Makecert.exe (Certificate Creation Tool) pro vygenerování testovacího certifikátu X.509 a umístěte ho do úložiště místního uživatele. Je nutné vygenerovat klíč pro výměnu a musíte jej vyrobit exportovatelný. Spusťte následující příkaz:

    makecert -r -pe -n "CN=XML_ENC_TEST_CERT" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my
    
  2. Vytvořte objekt X509Store a inicializujte ho, aby otevřel úložiště aktuálního uživatele.

    Dim store As New X509Store(StoreLocation.CurrentUser)
    
    X509Store store = new X509Store(StoreLocation.CurrentUser);
    
  3. Otevřete úložiště v režimu jen pro čtení.

    store.Open(OpenFlags.ReadOnly)
    
    store.Open(OpenFlags.ReadOnly);
    
  4. Inicializujte X509Certificate2Collection se všemi certifikáty v úložišti.

    Dim certCollection As X509Certificate2Collection = store.Certificates
    
    X509Certificate2Collection certCollection = store.Certificates;
    
  5. Projděte certifikáty v úložišti a najděte certifikát s odpovídajícím názvem. V tomto příkladu je certifikát pojmenován "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. Poté, co je certifikát nalezen, zavřete úložiště.

    store.Close()
    
    store.Close();
    
  7. Vytvořte objekt XmlDocument načtením souboru XML z disku. Objekt XmlDocument obsahuje element XML určený k zašifrování.

    Dim xmlDoc As New XmlDocument()
    
    XmlDocument xmlDoc = new XmlDocument();
    
  8. Nalezněte zadaný element v objektu XmlDocument a vytvořte nový objekt XmlElement představující element, který má být zašifrován. V tomto příkladu je zašifrován element "creditcard".

            Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
    
    
    XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
    
  9. Vytvořte novou instanci třídy EncryptedXml a použijte ji k zašifrování daného elementu pomocí certifikátu X.509. Metoda Encrypt vrací zašifrovaný element jako objekt EncryptedData.

    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. Nahraďte element z původního objektu XmlDocument elementem EncryptedData.

    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    
  11. Uložte objekt XmlDocument.

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

Příklad

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

Tento příklad předpokládá, že soubor s názvem "test.xml" existuje ve stejném adresáři jako Zkompilovaný program. Dále předpokládá, že "test.xml" obsahuje element "creditcard". Následující kód jazyka XML můžete umístit do souboru s názvem test.xml a použít jej v tomto příkladu.

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

Probíhá kompilace kódu

Zabezpečení

Certifikát X.509 použitý v tomto příkladu je pouze pro účely testování. Aplikace by měla používat certifikát X.509 generovaný důvěryhodnou certifikační autoritou nebo certifikát generovaný Microsoft Windows Certificate Server.

Viz také

Úkoly

Postupy: Dešifrovat elementy XML s certifikáty X.509

Odkaz

System.Security.Cryptography.Xml

Další zdroje

Šifrování XML a digitální podpisy