Porady: odszyfrowywanie elementów XML przy użyciu kluczy asymetrycznych
Klasy w System.Security.Cryptography.Xml przestrzeni nazw umożliwiają szyfrowanie i odszyfrowywanie 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 zalecenia World Wide Web Consortium (W3C) Składnia i przetwarzanie podpisów XML.
Uwaga
Kod w tym artykule dotyczy systemu Windows.
Przykład w tej procedurze odszyfrowuje element XML, który został zaszyfrowany przy użyciu metod opisanych w temacie Instrukcje: Szyfrowanie elementów XML przy użyciu kluczy asymetrycznych. Znajduje element <EncryptedData
> , odszyfrowuje element, a następnie zastępuje element oryginalnym elementem XML w postaci zwykłego tekstu.
W tym przykładzie odszyfrowuje element XML przy użyciu dwóch kluczy. Pobiera wcześniej wygenerowany klucz prywatny RSA z kontenera kluczy, a następnie używa klucza RSA do odszyfrowywania klucza sesji przechowywanego w <EncryptedKey
> elemecie <EncryptedData
> elementu. W tym przykładzie użyto klucza sesji do odszyfrowania elementu XML.
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 odszyfrować element XML przy użyciu klucza asymetrycznego
CspParameters Utwórz obiekt i określ nazwę kontenera kluczy.
CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
Pobierz wcześniej wygenerowany klucz asymetryczny z kontenera RSACryptoServiceProvider przy użyciu obiektu . Klucz jest automatycznie pobierany z kontenera kluczy podczas przekazywania CspParameters obiektu do konstruktora RSACryptoServiceProvider .
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
Utwórz nowy EncryptedXml obiekt, aby odszyfrować dokument.
// Create a new EncryptedXml object. EncryptedXml exml = new EncryptedXml(Doc);
' Create a new EncryptedXml object. Dim exml As New EncryptedXml(Doc)
Dodaj mapowanie klucza/nazwy, aby skojarzyć klucz RSA z elementem w dokumencie, który powinien zostać odszyfrowany. Musisz użyć tej samej nazwy klucza, który został użyty podczas szyfrowania dokumentu. Pamiętaj, że ta nazwa jest oddzielona od nazwy używanej do identyfikowania klucza w kontenerze kluczy określonym w kroku 1.
exml.AddKeyNameMapping(KeyName, Alg);
exml.AddKeyNameMapping(KeyName, Alg)
Wywołaj metodę , DecryptDocument aby odszyfrować <
EncryptedData
> element. Ta metoda używa klucza RSA do odszyfrowania klucza sesji i automatycznie używa klucza sesji do odszyfrowania elementu XML. Spowoduje to również automatyczne zastąpienie <EncryptedData
> elementu oryginalnym tekstem zwykłego tekstu.exml.DecryptDocument();
exml.DecryptDocument()
Zapisz dokument XML.
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 element XML, który został zaszyfrowany przy użyciu technik opisanych w temacie Instrukcje: Szyfrowanie elementów XML przy użyciu kluczy asymetrycznych.
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();
}
}
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.
ArgumentNullException.ThrowIfNull(Doc)
ArgumentNullException.ThrowIfNull(Alg)
ArgumentNullException.ThrowIfNull(KeyName)
' 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
Kompilowanie kodu
W projekcie przeznaczonym dla programu .NET Framework dołącz odwołanie do
System.Security.dll
elementu .W projekcie przeznaczonym dla platformy .NET Core lub .NET 5 zainstaluj pakiet NuGet System.Security.Cryptography.Xml.
Uwzględnij następujące przestrzenie nazw: System.Xml, System.Security.Cryptographyi System.Security.Cryptography.Xml.
Zabezpieczenia platformy .NET
Nigdy nie przechowuj symetrycznego klucza kryptograficznego w postaci zwykłego tekstu lub przetransferuj klucz symetryczny między maszynami w postaci zwykłego tekstu. Ponadto nigdy nie przechowuj ani nie przesyłaj klucza prywatnego pary kluczy asymetrycznych w postaci zwykłego tekstu. Aby uzyskać więcej informacji na temat symetrycznych i asymetrycznych kluczy kryptograficznych, zobacz Generowanie kluczy szyfrowania i odszyfrowywania.
Nigdy nie osadzaj klucza bezpośrednio w kodzie źródłowym. Klucze osadzone można łatwo odczytywać z zestawu przy użyciu Ildasm.exe (dezasembler IL) lub otwierając zestaw w edytorze tekstów, takim jak Notatnik.
Gdy skończysz używać klucza kryptograficznego, wyczyść go z pamięci, ustawiając każdy bajt na zero lub wywołując Clear metodę zarządzanej klasy kryptografii. Klucze kryptograficzne mogą być czasami odczytywane z pamięci przez debuger lub odczytywany z dysku twardego, jeśli lokalizacja pamięci jest stronicowana na dysk.