Поделиться через


Практическое руководство. Расшифровывание XML-элементов с помощью асимметричного ключа

Для шифрования и расшифровки элемента XML-документа могут использоваться классы, принадлежащие пространству имен System.Security.Cryptography.Xml. Шифрование XML-данных является стандартным способом обмена и хранения XML-данных, защищающим их от несанкционированного прочтения. Дополнительные сведения о стандарте шифрования XML см. в спецификации консорциума W3C XML Signature Syntax and Processing.

В этом примере производится расшифровка XML-элемента, зашифрованного с помощью методов, описанных в разделе Практическое руководство. Шифрование XML-элементов с помощью асимметричного ключа. Производится поиск элемента EncryptedData, его расшифровка и замещение элемента исходным XML-элементом в формате простого текста.

В этом примере расшифровка XML-элемента производится с использованием двух ключей. Ранее созданный закрытый ключ RSA извлекается из контейнера ключа и затем используется для расшифровки ключа сеанса, хранящегося в элементе EncryptedKey элемента EncryptedData. Далее в примере ключ сеанса используется для расшифровки XML-элемента.

Этот пример применим в том случае, если необходимо обеспечить общий доступ к зашифрованным данным со стороны нескольких приложений, или если приложение должно сохранять зашифрованные данные между запусками.

Расшифровка XML-элемента с помощью асимметричного ключа

  1. Создайте объект CspParameters и укажите имя контейнера ключа.

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
    
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
    
  2. Извлеките ранее созданный асимметричный ключ из контейнера с помощью объекта RSACryptoServiceProvider. Ключ автоматически извлекается из контейнера ключа при передаче объекта CspParameters конструктору RSACryptoServiceProvider.

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. Создайте новый объект EncryptedXml для расшифровки документа.

    ' Create a new EncryptedXml object.
    Dim exml As New EncryptedXml(Doc)
    
            // Create a new EncryptedXml object.
            EncryptedXml exml = new EncryptedXml(Doc);
    
  4. Добавьте сопоставление ключа и имени, чтобы привязать ключ RSA к элементу, подлежащему расшифровке, в документе. Для ключа следует использовать то же имя, что и при шифровании документа. Обратите внимание, что это имя независимо от имени, использовавшегося для определения ключа в контейнере ключа, которое было указано на этапе 1.

    exml.AddKeyNameMapping(KeyName, Alg)
    
            exml.AddKeyNameMapping(KeyName, Alg);
    
  5. Вызовите метод DecryptDocument для расшифровки элемента EncryptedData. Этот метод использует ключ RSA для расшифровки ключа сеанса и автоматически использует ключ сеанса для расшифровки XML-элемента. Он также автоматически замещает элемент EncryptedData исходным элементом в формате простого текста.

    exml.DecryptDocument()
    
            exml.DecryptDocument();
    
  6. Сохраните XML-документ.

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

Пример

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

    }

}

В этом примере предполагается, что файл с именем test.xml существует в том же каталоге, что и скомпилированная программа. Также предполагается, что test.xml содержит XML-элемент, зашифрованный с помощью метода, описанного в разделе Практическое руководство. Шифрование XML-элементов с помощью асимметричного ключа.

Компиляция кода

Безопасность

Не следует хранить симметричный криптографический ключ в виде простого текста или передавать его в таком формате между компьютерами. Кроме того, не следует хранить или передавать закрытый ключ асимметричной пары ключей в виде простого текста. Дополнительные сведения о симметричных и асимметричных криптографических ключах см. в разделе Создание ключей для шифрования и расшифровки.

Не следует внедрять ключ непосредственно в исходный код. Внедренные ключи могут быть легко прочитаны из сборки с помощью программы Ildasm.exe (дизассемблер MSIL) или шестнадцатеричного редактора, либо путем открытия сборки в текстовом редакторе, таком как "Блокнот".

По завершении использования криптографического ключа его следует удалить из памяти, обнулив каждый байт или вызвав метод Clear управляемого криптографического класса. Иногда криптографические ключи могут считываться из памяти отладчиком или считываться с жесткого диска, если данная область памяти выгружена на диск.

См. также

Задачи

Практическое руководство. Шифрование XML-элементов с помощью асимметричного ключа

Ссылки

System.Security.Cryptography.Xml

Другие ресурсы

Шифрование и цифровые подписи в XML

Журнал изменений

Дата

Журнал

Причина

Июль 2010

Исправлены примеры, которые были приведены в неправильном порядке.

Обратная связь от клиента.