Практическое руководство. Расшифровывание XML-элементов с помощью асимметричного ключа
Обновлен: Ноябрь 2007
Для шифрования и расшифровки элемента XML-документа могут использоваться классы, принадлежащие пространству имен System.Security.Cryptography.Xml. Шифрование XML-данных является стандартным способом обмена и хранения XML-данных, защищающим их от несанкционированного прочтения. Дополнительные сведения о стандарте шифрования XML-данных см. в спецификации консорциума W3C по шифрованию XML-данных, расположенной на веб-узле по адресу: http://www.w3.org/TR/xmldsig-core/.
В этом примере производится расшифровка XML-элемента, зашифрованного с помощью метода, описанного в разделе Практическое руководство. Шифрование XML-элементов с помощью асимметричного ключа. Производится поиск элемента EncryptedData, его расшифровка и замещение элемента исходным XML-элементом в формате простого текста.
В этом примере расшифровка XML-элемента производится с использованием двух ключей. Ранее созданный закрытый ключ RSA извлекается из контейнера ключа и затем используется для расшифровки ключа сеанса, хранящегося в элементе EncryptedKey элемента EncryptedData. Далее в примере ключ сеанса используется для расшифровки XML-элемента.
Этот пример применим в том случае, если необходимо обеспечить общий доступ к зашифрованным данным со стороны нескольких приложений, или если приложение должно сохранять зашифрованные данные между запусками.
Расшифровка XML-элемента с помощью асимметричного ключа
Создайте объект CspParameters и укажите имя контейнера ключа.
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
Извлеките ранее созданный асимметричный ключ из контейнера с помощью объекта RSACryptoServiceProvider. Ключ автоматически извлекается из контейнера ключа при передаче объекта CspParameters конструктору конструктора RSACryptoServiceProvider.
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
Создайте новый объект EncryptedXml для расшифровки документа.
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
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); }
Добавьте сопоставление ключа и имени, чтобы привязать ключ RSA к элементу, подлежащему расшифровке, в документе. Для ключа следует использовать то же имя, что и при шифровании документа. Обратите внимание, что это имя независимо от имени, использовавшегося для определения ключа в контейнере ключа, которое было указано на этапе 1.
' Create a new EncryptedXml object. Dim exml As New EncryptedXml(Doc)
// Create a new EncryptedXml object. EncryptedXml exml = new EncryptedXml(Doc);
Вызовите метод DecryptDocument для расшифровки элемента EncryptedData. Этот метод использует ключ RSA для расшифровки ключа сеанса и автоматически использует ключ сеанса для расшифровки XML-элемента. Он также автоматически замещает элемент EncryptedData исходным элементом в формате простого текста.
exml.AddKeyNameMapping(KeyName, Alg)
exml.AddKeyNameMapping(KeyName, Alg);
Сохраните XML-документ.
exml.DecryptDocument()
exml.DecryptDocument();
Пример
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-элементов с помощью асимметричного ключа.
Компиляция кода
Для компиляции этого примера может потребоваться включить ссылку на System.Security.dll.
Включите следующие пространства имен: System.Xml, System.Security.Cryptography и System.Security.Cryptography.Xml.
Безопасность
Не следует хранить симметричный криптографический ключ в виде простого текста или передавать его в таком формате между компьютерами. Кроме того, не следует хранить или передавать закрытый ключ асимметричной пары ключей в виде простого текста. Дополнительные сведения о симметричных и асимметричных криптографических ключах см. в разделе Создание ключей для шифрования и расшифровки.
Не следует внедрять ключ непосредственно в исходный код. Внедренные ключи могут быть легко прочитаны из сборки с помощью программы Дизассемблер MSIL (Ildasm.exe) или шестнадцатеричного редактора, либо путем открытия сборки в текстовом редакторе, таком как "Блокнот".
По завершении использования криптографического ключа его следует удалить из памяти, обнулив каждый байт или вызвав метод Clear управляемого криптографического класса. Иногда криптографические ключи могут считываться из памяти отладчиком или считываться с жесткого диска, если данная область памяти выгружена на диск.
См. также
Задачи
Практическое руководство. Шифрование XML-элементов с помощью асимметричного ключа
Ссылки
System.Security.Cryptography.Xml