Udostępnij za pośrednictwem


Porady: szyfrowanie elementów XML za pomocą certyfikatów X.509

Klasy w System.Security.Cryptography.Xml przestrzeni nazw umożliwiają szyfrowanie elementu w dokumencie XML. Szyfrowanie XML to standardowy sposób wymiany lub przechowywania zaszyfrowanych danych XML bez obaw o łatwe odczytywanie danych. Aby uzyskać więcej informacji na temat standardu szyfrowania XML, zobacz specyfikację World Wide Web Consortium (W3C) dotyczącą szyfrowania XML znajdującego się w https://www.w3.org/TR/xmldsig-core/lokalizacji .

Szyfrowanie XML umożliwia zastąpienie dowolnego elementu XML lub dokumentu elementem zawierającym <EncryptedData> zaszyfrowane dane XML. Element <EncryptedData> może zawierać elementy podrzędne zawierające informacje o kluczach i procesach używanych podczas szyfrowania. Szyfrowanie XML umożliwia dokumentowi zawieranie wielu zaszyfrowanych elementów i umożliwia wielokrotne szyfrowanie elementu. Przykładowy kod w tej procedurze pokazuje, jak utworzyć <EncryptedData> element wraz z kilkoma innymi elementami podrzędnymi, których można użyć później podczas odszyfrowywania.

W tym przykładzie szyfruje element XML przy użyciu dwóch kluczy. Przykład programowo pobiera certyfikat i używa go do szyfrowania elementu XML przy użyciu Encrypt metody . Encrypt Metoda wewnętrznie tworzy oddzielny klucz sesji i używa go do szyfrowania dokumentu XML. Ta metoda szyfruje klucz sesji i zapisuje go wraz z zaszyfrowanym kodem XML w ramach nowego <EncryptedData> elementu.

Aby odszyfrować element XML, wywołaj metodę DecryptDocument , która automatycznie pobiera certyfikat X.509 z magazynu i wykonuje niezbędne odszyfrowywanie. Aby uzyskać więcej informacji na temat odszyfrowywania elementu XML, który został zaszyfrowany przy użyciu tej procedury, zobacz How to: Decrypt XML Elements with X.509 Certificates (Jak: odszyfrowywać elementy XML przy użyciu certyfikatów X.509).

Ten przykład jest odpowiedni w sytuacjach, w których wiele aplikacji musi udostępniać zaszyfrowane dane lub gdzie aplikacja musi zapisywać zaszyfrowane dane między godzinami jej uruchomienia.

Aby zaszyfrować element XML z certyfikatem X.509

Aby uruchomić ten przykład, należy utworzyć certyfikat testowy i zapisać go w magazynie certyfikatów. Instrukcje dotyczące tego zadania są udostępniane tylko dla narzędzia do tworzenia certyfikatów systemu Windows (Makecert.exe).

  1. Użyj Makecert.exe , aby wygenerować testowy certyfikat X.509 i umieścić go w magazynie użytkowników lokalnych. Musisz wygenerować klucz wymiany i należy go wyeksportować. Uruchom następujące polecenie:

    makecert -r -pe -n "CN=XML_ENC_TEST_CERT" -b 01/01/2020 -e 01/01/2025 -sky exchange -ss my  
    
  2. X509Store Utwórz obiekt i zainicjuj go, aby otworzyć bieżący magazyn użytkowników.

    X509Store store = new X509Store(StoreLocation.CurrentUser);
    
    Dim store As New X509Store(StoreLocation.CurrentUser)
    
  3. Otwórz magazyn w trybie tylko do odczytu.

    store.Open(OpenFlags.ReadOnly);
    
    store.Open(OpenFlags.ReadOnly)
    
  4. Zainicjuj element X509Certificate2Collection ze wszystkimi certyfikatami w magazynie.

    X509Certificate2Collection certCollection = store.Certificates;
    
    Dim certCollection As X509Certificate2Collection = store.Certificates
    
  5. Wylicz certyfikaty w magazynie i znajdź certyfikat z odpowiednią nazwą. W tym przykładzie certyfikat ma nazwę "CN=XML_ENC_TEST_CERT".

    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;
        }
    }
    
    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
    
  6. Zamknij magazyn po zlokalizowaniu certyfikatu.

    store.Close();
    
    store.Close()
    
  7. XmlDocument Utwórz obiekt, ładując plik XML z dysku. Obiekt XmlDocument zawiera element XML do zaszyfrowania.

    XmlDocument xmlDoc = new XmlDocument();
    
    Dim xmlDoc As New XmlDocument()
    
  8. Znajdź określony element w XmlDocument obiekcie i utwórz nowy XmlElement obiekt reprezentujący element, który chcesz zaszyfrować. W tym przykładzie "creditcard" element jest zaszyfrowany.

    XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
    
    Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
    
    
  9. Utwórz nowe wystąpienie EncryptedXml klasy i użyj go do zaszyfrowania określonego elementu przy użyciu certyfikatu X.509. Metoda Encrypt zwraca zaszyfrowany element jako EncryptedData obiekt.

    EncryptedXml eXml = new EncryptedXml();
    
    // Encrypt the element.
    EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);
    
    Dim eXml As New EncryptedXml()
    
    ' Encrypt the element.
    Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
    
  10. Zastąp element z oryginalnego XmlDocument obiektu elementem EncryptedData .

    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    
  11. XmlDocument Zapisz obiekt.

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

Przykład

W tym przykładzie przyjęto założenie, że plik o nazwie "test.xml" istnieje w tym samym katalogu co skompilowany program. Przyjęto również założenie, że "test.xml" zawiera "creditcard" element . Poniższy kod XML można umieścić w pliku o nazwie test.xml i użyć go w tym przykładzie.

<root>  
    <creditcard>  
        <number>19834209</number>  
        <expiry>02/02/2002</expiry>  
    </creditcard>  
</root>  
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 XmlElement 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);
    }
}
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


    Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal Cert As X509Certificate2)
        ' Check the arguments.  
        ArgumentNullException.ThrowIfNull(Doc)
        ArgumentNullException.ThrowIfNull(ElementToEncryptName)
        ArgumentNullException.ThrowIfNull(Cert)
        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' 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

Kompilowanie kodu

Zabezpieczenia platformy .NET

Certyfikat X.509 używany w tym przykładzie jest przeznaczony tylko do celów testowych. Aplikacje powinny używać certyfikatu X.509 wygenerowanego przez zaufany urząd certyfikacji.

Zobacz też