Прочитать на английском

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


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

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

Примечание

Код, приведенный в этой статье, применяется к Windows.

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

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

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

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

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

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

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

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

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

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

    xmlDoc.Save("test.xml");
    

Пример

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


using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Runtime.Versioning;

[SupportedOSPlatform("windows")]
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();
    }
}

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

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

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

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

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

См. также