Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
U kunt de klassen in de System.Security.Cryptography.Xml naamruimte gebruiken om een element in een XML-document te versleutelen. XML-versleuteling is een standaardmethode voor het uitwisselen of opslaan van versleutelde XML-gegevens, zonder dat u zich zorgen hoeft te maken over de gegevens die gemakkelijk kunnen worden gelezen. Zie de W3C-specificatie (World Wide Web Consortium) voor XML-versleuteling op https://www.w3.org/TR/xmldsig-core/voor meer informatie over de XML-versleutelingsstandaard.
U kunt XML-versleuteling gebruiken om elk XML-element of document te vervangen door een <EncryptedData>
element dat de versleutelde XML-gegevens bevat. Het <EncryptedData>
element kan ook subelementen bevatten die informatie bevatten over de sleutels en processen die tijdens de versleuteling worden gebruikt. MET XML-versleuteling kan een document meerdere versleutelde elementen bevatten en kan een element meerdere keren worden versleuteld. In het codevoorbeeld in deze procedure ziet u hoe u een <EncryptedData>
element maakt, samen met verschillende andere subelementen die u later tijdens de ontsleuteling kunt gebruiken.
In dit voorbeeld wordt een XML-element versleuteld met twee sleutels. Er wordt een openbaar/persoonlijk RSA-sleutelpaar gegenereerd en het sleutelpaar opgeslagen in een beveiligde sleutelcontainer. In het voorbeeld wordt vervolgens een afzonderlijke sessiesleutel gemaakt met behulp van het AES-algoritme (Advanced Encryption Standard). In het voorbeeld wordt de AES-sessiesleutel gebruikt om het XML-document te versleutelen en wordt vervolgens de openbare RSA-sleutel gebruikt om de AES-sessiesleutel te versleutelen. Ten slotte slaat het voorbeeld de versleutelde AES-sessiesleutel en de versleutelde XML-gegevens op in het XML-document in een nieuw <EncryptedData
> element.
Als u het XML-element wilt ontsleutelen, haalt u de persoonlijke RSA-sleutel op uit de sleutelcontainer, gebruikt u het om de sessiesleutel te ontsleutelen en gebruikt u vervolgens de sessiesleutel om het document te ontsleutelen. Zie Voor meer informatie over het ontsleutelen van een XML-element dat is versleuteld met behulp van deze procedure : XML-elementen ontsleutelen met asymmetrische sleutels.
Dit voorbeeld is geschikt voor situaties waarin meerdere toepassingen versleutelde gegevens moeten delen of waar een toepassing versleutelde gegevens moet opslaan tussen de tijden waarop deze wordt uitgevoerd.
Een XML-element versleutelen met een asymmetrische sleutel
Maak een CspParameters object en geef de naam van de sleutelcontainer op.
CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
Genereer een asymmetrische sleutel met behulp van de RSACryptoServiceProvider klasse. De sleutel wordt automatisch opgeslagen in de sleutelcontainer wanneer u het CspParameters object doorgeeft aan de constructor van de RSACryptoServiceProvider klasse. Deze sleutel wordt gebruikt om de AES-sessiesleutel te versleutelen en kan later worden opgehaald om deze te ontsleutelen.
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
Maak een XmlDocument object door een XML-bestand van de schijf te laden. Het XmlDocument object bevat het XML-element dat moet worden versleuteld.
// 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); }
' 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
Zoek het opgegeven element in het XmlDocument object en maak een nieuw XmlElement object om het element weer te geven dat u wilt versleutelen. In dit voorbeeld wordt het
"creditcard"
element versleuteld.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"); }
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(EncryptionElement)(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
Maak een nieuwe sessiesleutel met behulp van de Aes klasse. Met deze sleutel wordt het XML-element versleuteld en vervolgens versleuteld en in het XML-document geplaatst.
// Create an AES key. sessionKey = Aes.Create();
' Create an AES key. sessionKey = Aes.Create()
Maak een nieuw exemplaar van de EncryptedXml klasse en gebruik deze om het opgegeven element te versleutelen met behulp van de sessiesleutel. De EncryptData methode retourneert het versleutelde element als een matrix van versleutelde bytes.
EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
Dim eXml As New EncryptedXml() Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, sessionKey, False)
Maak een EncryptedData object en vul het met de URL-id van het versleutelde XML-element. Met deze URL-id weet een ontsleutelingspartij dat de XML een versleuteld element bevat. U kunt het XmlEncElementUrl veld gebruiken om de URL-id op te geven. Het XML-element zonder opmaak wordt vervangen door een
<EncryptedData>
element dat door dit EncryptedData object wordt ingekapseld.EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID;
Dim edElement As New EncryptedData() edElement.Type = EncryptedXml.XmlEncElementUrl edElement.Id = EncryptionElementID
Maak een EncryptionMethod object dat is geïnitialiseerd naar de URL-id van het cryptografische algoritme dat wordt gebruikt om de sessiesleutel te genereren. Geef het EncryptionMethod object door aan de EncryptionMethod eigenschap.
edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
edElement.EncryptionMethod = New EncryptionMethod(EncryptedXml.XmlEncAES256Url)
Maak een EncryptedKey object dat de versleutelde sessiesleutel bevat. Versleutel de sessiesleutel, voeg deze toe aan het EncryptedKey object en voer een sessiesleutelnaam en sleutel-id-URL in.
EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
Dim ek As New EncryptedKey() Dim encryptedKey As Byte() = EncryptedXml.EncryptKey(sessionKey.Key, Alg, False) ek.CipherData = New CipherData(encryptedKey) ek.EncryptionMethod = New EncryptionMethod(EncryptedXml.XmlEncRSA15Url)
Maak een nieuw DataReference object waarmee de versleutelde gegevens worden toegewezen aan een bepaalde sessiesleutel. Met deze optionele stap kunt u eenvoudig opgeven dat meerdere delen van een XML-document met één sleutel zijn versleuteld.
DataReference dRef = new DataReference(); // Specify the EncryptedData URI. dRef.Uri = "#" + EncryptionElementID; // Add the DataReference to the EncryptedKey. ek.AddReference(dRef);
Dim dRef As New DataReference() ' Specify the EncryptedData URI. dRef.Uri = "#" + EncryptionElementID ' Add the DataReference to the EncryptedKey. ek.AddReference(dRef)
Voeg de versleutelde sleutel toe aan het EncryptedData object.
edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
edElement.KeyInfo.AddClause(New KeyInfoEncryptedKey(ek))
Maak een nieuw KeyInfo object om de naam van de RSA-sleutel op te geven. Voeg het toe aan het EncryptedData object. Dit helpt de ontsleutelingspartij om de juiste asymmetrische sleutel te identificeren die moet worden gebruikt bij het ontsleutelen van de sessiesleutel.
// Create a new KeyInfoName element. KeyInfoName kin = new KeyInfoName(); // Specify a name for the key. kin.Value = KeyName; // Add the KeyInfoName element to the // EncryptedKey object. ek.KeyInfo.AddClause(kin);
' Create a new KeyInfoName element. Dim kin As New KeyInfoName() ' Specify a name for the key. kin.Value = KeyName ' Add the KeyInfoName element to the ' EncryptedKey object. ek.KeyInfo.AddClause(kin)
Voeg de versleutelde elementgegevens toe aan het EncryptedData object.
edElement.CipherData.CipherValue = encryptedElement;
edElement.CipherData.CipherValue = encryptedElement
Vervang het element van het oorspronkelijke XmlDocument object door het EncryptedData element.
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
Sla het XmlDocument object op.
xmlDoc.Save("test.xml");
xmlDoc.Save("test.xml")
Opmerking
In dit voorbeeld wordt ervan uitgegaan dat een bestand met de naam "test.xml"
bestaat in dezelfde map als het gecompileerde programma. Ook wordt ervan uitgegaan dat dit "test.xml"
een "creditcard"
element bevat. U kunt de volgende XML in een bestand met de naam test.xml
plaatsen en gebruiken in dit voorbeeld.
<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.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);
}
// Create a new CspParameters object to specify
// a key container.
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
// Create a new RSA key and save it in the container. This key will encrypt
// a symmetric key, which will then be encrypted in the XML document.
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
try
{
// Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", "EncryptedElement1", rsaKey, "rsaKey");
// 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);
Decrypt(xmlDoc, rsaKey, "rsaKey");
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 Encrypt(XmlDocument Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName)
{
// Check the arguments.
if (Doc == null)
throw new ArgumentNullException("Doc");
if (ElementToEncrypt == null)
throw new ArgumentNullException("ElementToEncrypt");
if (EncryptionElementID == null)
throw new ArgumentNullException("EncryptionElementID");
if (Alg == null)
throw new ArgumentNullException("Alg");
if (KeyName == null)
throw new ArgumentNullException("KeyName");
////////////////////////////////////////////////
// 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");
}
Aes? sessionKey = null;
try
{
//////////////////////////////////////////////////
// Create a new instance of the EncryptedXml class
// and use it to encrypt the XmlElement with the
// a new random symmetric key.
//////////////////////////////////////////////////
// Create an AES key.
sessionKey = Aes.Create();
EncryptedXml eXml = new EncryptedXml();
byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
////////////////////////////////////////////////
// Construct an EncryptedData object and populate
// it with the desired encryption information.
////////////////////////////////////////////////
EncryptedData edElement = new EncryptedData();
edElement.Type = EncryptedXml.XmlEncElementUrl;
edElement.Id = EncryptionElementID;
// Create an EncryptionMethod element so that the
// receiver knows which algorithm to use for decryption.
edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
// Encrypt the session key and add it to an EncryptedKey element.
EncryptedKey ek = new EncryptedKey();
byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false);
ek.CipherData = new CipherData(encryptedKey);
ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
// Create a new DataReference element
// for the KeyInfo element. This optional
// element specifies which EncryptedData
// uses this key. An XML document can have
// multiple EncryptedData elements that use
// different keys.
DataReference dRef = new DataReference();
// Specify the EncryptedData URI.
dRef.Uri = "#" + EncryptionElementID;
// Add the DataReference to the EncryptedKey.
ek.AddReference(dRef);
// Add the encrypted key to the
// EncryptedData object.
edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
// Set the KeyInfo element to specify the
// name of the RSA key.
// Create a new KeyInfoName element.
KeyInfoName kin = new KeyInfoName();
// Specify a name for the key.
kin.Value = KeyName;
// Add the KeyInfoName element to the
// EncryptedKey object.
ek.KeyInfo.AddClause(kin);
// Add the encrypted element data to the
// EncryptedData object.
edElement.CipherData.CipherValue = encryptedElement;
////////////////////////////////////////////////////
// Replace the element from the original XmlDocument
// object with the EncryptedData element.
////////////////////////////////////////////////////
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
}
finally
{
sessionKey?.Clear();
}
}
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
Class Program
Shared 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
' Create a new CspParameters object to specify
' a key container.
Dim cspParams As New CspParameters()
cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
' Create a new RSA key and save it in the container. This key will encrypt
' a symmetric key, which will then be encrypted in the XML document.
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
Try
' Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", "EncryptedElement1", rsaKey, "rsaKey")
' 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)
Decrypt(xmlDoc, rsaKey, "rsaKey")
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
Public Shared Sub Encrypt(ByVal Doc As XmlDocument, ByVal EncryptionElement As String, ByVal EncryptionElementID As String, ByVal Alg As RSA, ByVal KeyName As String)
' Check the arguments.
ArgumentNullException.ThrowIfNull(Doc)
ArgumentNullException.ThrowIfNull(EncryptionElement)
ArgumentNullException.ThrowIfNull(EncryptionElementID)
ArgumentNullException.ThrowIfNull(Alg)
ArgumentNullException.ThrowIfNull(KeyName)
'//////////////////////////////////////////////
' Find the specified element in the XmlDocument
' object and create a new XmlElement object.
'//////////////////////////////////////////////
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(EncryptionElement)(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
Dim sessionKey As Aes = Nothing
Try
'////////////////////////////////////////////////
' Create a new instance of the EncryptedXml class
' and use it to encrypt the XmlElement with the
' a new random symmetric key.
'////////////////////////////////////////////////
' Create an AES key.
sessionKey = Aes.Create()
Dim eXml As New EncryptedXml()
Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, sessionKey, False)
'//////////////////////////////////////////////
' Construct an EncryptedData object and populate
' it with the desired encryption information.
'//////////////////////////////////////////////
Dim edElement As New EncryptedData()
edElement.Type = EncryptedXml.XmlEncElementUrl
edElement.Id = EncryptionElementID
' Create an EncryptionMethod element so that the
' receiver knows which algorithm to use for decryption.
edElement.EncryptionMethod = New EncryptionMethod(EncryptedXml.XmlEncAES256Url)
' Encrypt the session key and add it to an EncryptedKey element.
Dim ek As New EncryptedKey()
Dim encryptedKey As Byte() = EncryptedXml.EncryptKey(sessionKey.Key, Alg, False)
ek.CipherData = New CipherData(encryptedKey)
ek.EncryptionMethod = New EncryptionMethod(EncryptedXml.XmlEncRSA15Url)
' Create a new DataReference element
' for the KeyInfo element. This optional
' element specifies which EncryptedData
' uses this key. An XML document can have
' multiple EncryptedData elements that use
' different keys.
Dim dRef As New DataReference()
' Specify the EncryptedData URI.
dRef.Uri = "#" + EncryptionElementID
' Add the DataReference to the EncryptedKey.
ek.AddReference(dRef)
' Add the encrypted key to the
' EncryptedData object.
edElement.KeyInfo.AddClause(New KeyInfoEncryptedKey(ek))
' Set the KeyInfo element to specify the
' name of the RSA key.
' Create a new KeyInfoName element.
Dim kin As New KeyInfoName()
' Specify a name for the key.
kin.Value = KeyName
' Add the KeyInfoName element to the
' EncryptedKey object.
ek.KeyInfo.AddClause(kin)
' Add the encrypted element data to the
' EncryptedData object.
edElement.CipherData.CipherValue = encryptedElement
'//////////////////////////////////////////////////
' Replace the element from the original XmlDocument
' object with the EncryptedData element.
'//////////////////////////////////////////////////
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
Catch e As Exception
' re-throw the exception.
Throw
Finally
If Not (sessionKey Is Nothing) Then
sessionKey.Clear()
End If
End Try
End Sub
Public Shared 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 Class
De code compileren
- Neem in een project dat is gericht op .NET Framework een verwijzing naar
System.Security.dll
. - Installeer nuGet-pakket System.Security.Cryptography.Xml in een project dat is gericht op .NET Core of .NET 5.
- Neem de volgende naamruimten op: System.Xml, System.Security.Cryptographyen System.Security.Cryptography.Xml.
.NET-beveiliging
Sla nooit een symmetrische cryptografische sleutel op in platte tekst of draag een symmetrische sleutel over tussen computers in platte tekst. Sla de persoonlijke sleutel van een asymmetrisch sleutelpaar bovendien nooit op in tekst zonder opmaak. Zie Sleutels genereren voor versleuteling en ontsleuteling voor meer informatie over symmetrische en asymmetrische cryptografische sleutels.
Tip
Gebruik Secret Manager voor beveiligde geheime opslag voor ontwikkeling. Overweeg in productie een product zoals Azure Key Vault.
Sluit nooit rechtstreeks een sleutel in uw broncode in. Ingesloten sleutels kunnen eenvoudig worden gelezen vanuit een assembly met behulp van de Ildasm.exe (IL Disassembler) of door de assembly te openen in een teksteditor zoals Kladblok.
Wanneer u klaar bent met het gebruik van een cryptografische sleutel, wist u deze van het geheugen door elke byte in te stellen op nul of door de Clear methode van de beheerde cryptografieklasse aan te roepen. Cryptografische sleutels kunnen soms vanuit het geheugen worden gelezen door een foutopsporingsprogramma of worden gelezen vanaf een harde schijf als de geheugenlocatie naar de schijf wordt gepaginad.