Como: Criptografar elementos XML com assimétrica de chaves
Você pode usar as classes no System.Security.Cryptography.Xml namespace para criptografar um elemento dentro de um documento XML. Criptografia XML é uma forma padrão para trocar ou armazenar dados criptografados do XML, sem se preocupar com os dados que está sendo lidos com com facilidade.Para obter mais informações sobre a criptografia XML padrão, consulte que a especificação de World Wide Web Consortium (W3C) para criptografia XML localizado em http://www.w3.org/TR/xmldsig-core/.
Você pode usar a criptografia XML para substituir qualquer elemento XML ou documento com um <EncryptedData>elemento que contém os dados XML criptografados. O <EncryptedData>elemento também pode conter elementos de sub-rotina que incluem informações sobre as chaves e os processos usados durante a criptografia. Criptografia XML permite que um documento contêm vários elementos criptografados e permite que um elemento a ser criptografado várias vezes.O exemplo de código neste procedimento mostra como criar um <EncryptedData>elemento junto com vários outros elementos de sub-rotina que você pode usar mais tarde durante a descriptografia.
Este exemplo criptografa um elemento XML usando duas chaves.Ele gera um público RSA / emparelharticular emparelhar de chaves e salva o emparelhar de chaves emparelhara um contêiner de chave seguro.O exemplo, em seguida, cria uma chave de sessão separada usando o algoritmo AES (criptografia AES), também chamado algoritmo Rijndael.O exemplo usa a chave de sessão AES para criptografar o documento XML e, em seguida, usa a chave pública RSA para criptografar a chave de sessão AES.Finalmente, o exemplo salva a chave de sessão AES criptografada e os dados criptografados do XML ao documento XML em um novo <EncryptedData>elemento.
Para descriptografar o elemento XML, recuperar a chave privada RSA do contêiner de chave, use-o para descriptografar a chave de sessão e, em seguida, usam a chave de sessão para descriptografar o documento.Para obter mais informações sobre como descriptografar um elemento XML que foi criptografado usando este procedimento, consulte Como: Decrypt elementos XML com teclas Asymmetric.
Este exemplo é apropriado para situações em que vários aplicativos precisam compartilhe dados criptografados ou onde um aplicativo precisa salvar os dados criptografados entre as horas que ele seja executado.
Para criptografar um elemento XML com uma chave assimétrica
Criar um CspParameters objeto e especifique o nome do contêiner de chave.
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
Gerar uma chave simétrica usando o RSACryptoServiceProvider classe. A chave é salvo automaticamente para o contêiner de chave quando você passar o CspParameters objeto para o construtor das RSACryptoServiceProvider classe. Essa chave será usada para criptografar a chave de sessão AES e pode ser recuperado posteriormente descriptografá-lo.
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
criar an XmlDocument objeto carregando um arquivo XML do disco. The XmlDocument objeto contém o elemento XML para criptografar.
' 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 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); }
Localize o elemento especificado no XmlDocument objeto e crie um novo XmlElement objeto para representar o elemento que deseja criptografar. Neste exemplo, a "creditcard" elemento é criptografado.
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(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
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"); }
Criar uma nova chave de sessão usando o RijndaelManaged classe. Essa chave irá criptografar o elemento XML e, em seguida, ser criptografado propriamente dito e inserido no documento XML.
' Create a 256 bit Rijndael key. sessionKey = New RijndaelManaged() sessionKey.KeySize = 256
// Create a 256 bit Rijndael key. sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256;
Criar uma nova instância do EncryptedXml classe e usá-lo para criptografar o elemento especificado usando a chave de sessão. The EncryptData método retorna o elemento criptografado sistema autônomo uma matriz de bytes criptografados.
Dim eXml As New EncryptedXml() Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, sessionKey, False)
EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
Construir um EncryptedData objeto e preenchê-lo com o identificador de URL do elemento XML criptografado. Esse identificador URL permite uma festa de descriptografia sabe que o XML contém um elemento criptografado.Você pode usar o XmlEncElementUrl campo para especificar o identificador de URL. O elemento XML de texto não criptografado será substituído por um <EncrypotedData>encapsulado por este elemento EncryptedData objeto.
Dim edElement As New EncryptedData() edElement.Type = EncryptedXml.XmlEncElementUrl edElement.Id = EncryptionElementID
EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID;
criar an EncryptionMethod objeto que é inicializado para o identificador de URL do algoritmo de criptografia usado para gerar a chave de sessão. Passar o EncryptionMethod objeto para o EncryptionMethod propriedade.
edElement.EncryptionMethod = New EncryptionMethod(EncryptedXml.XmlEncAES256Url)
edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
Crie um EncryptedKey objeto para conter a chave de sessão criptografada. Criptografar a chave de sessão, adicione-à EncryptedKey objeto e digite um nome de chave de sessão e a URL do identificador de chave.
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)
EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
Criar um novo DataReference objeto que mapeia os dados criptografados a uma chave de sessão específica. Essa etapa opcional permite que você especifique com com facilidade que várias partes de um documento XML foram criptografados por uma única chave.
Dim dRef As New DataReference() ' Specify the EncryptedData URI. dRef.Uri = "#" + EncryptionElementID ' Add the DataReference to the EncryptedKey. ek.AddReference(dRef)
DataReference dRef = new DataReference(); // Specify the EncryptedData URI. dRef.Uri = "#" + EncryptionElementID; // Add the DataReference to the EncryptedKey. ek.AddReference(dRef);
Adicione a chave criptografada para o EncryptedData objeto.
edElement.KeyInfo.AddClause(New KeyInfoEncryptedKey(ek))
edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
Criar um novo KeyInfo objeto para especificar o nome da chave RSA. Adicione-à EncryptedData objeto. Isso ajuda a festa descriptografia identificar a chave assimétrica correta a ser usado ao descriptografar a chave de sessão.
' Create a new KeyInfo element. edElement.KeyInfo = New KeyInfo() ' 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)
// Create a new KeyInfo element. edElement.KeyInfo = new KeyInfo(); // 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);
Adicionar os dados criptografados elemento o EncryptedData objeto.
edElement.CipherData.CipherValue = encryptedElement
edElement.CipherData.CipherValue = encryptedElement;
Substituir o elemento do originalXmlDocument objeto com o EncryptedData elemento.
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
salvar o XmlDocument objeto.
xmlDoc.Save("test.xml")
xmlDoc.Save("test.xml");
Exemplo
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
' 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 encryped 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)
Catch e As Exception
Console.WriteLine(e.Message)
Finally
' Clear the RSA key.
rsaKey.Clear()
End Try
Console.ReadLine()
End Sub
Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal EncryptionElementID As String, ByVal Alg As RSA, ByVal KeyName As String)
' Check the arguments.
If Doc Is Nothing Then
Throw New ArgumentNullException("Doc")
End If
If ElementToEncryptName Is Nothing Then
Throw New ArgumentNullException("ElementToEncrypt")
End If
If EncryptionElementID Is Nothing Then
Throw New ArgumentNullException("EncryptionElementID")
End If
If Alg Is Nothing Then
Throw New ArgumentNullException("Alg")
End If
If KeyName Is Nothing Then
Throw New ArgumentNullException("KeyName")
End If
''''''''''''''''''''''''''''''''''''''''''''''''''
' Find the specified element in the XmlDocument
' object and create a new XmlElemnt object.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(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 RijndaelManaged = 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 a 256 bit Rijndael key.
sessionKey = New RijndaelManaged()
sessionKey.KeySize = 256
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 KeyInfo element.
edElement.KeyInfo = New KeyInfo()
' 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 e
Finally
If Not (sessionKey Is Nothing) Then
sessionKey.Clear()
End If
End Try
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);
}
// 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 encryped 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);
}
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 XmlElemnt 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");
}
RijndaelManaged 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 a 256 bit Rijndael key.
sessionKey = new RijndaelManaged();
sessionKey.KeySize = 256;
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 KeyInfo element.
edElement.KeyInfo = new KeyInfo();
// 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);
}
catch(Exception e)
{
// re-throw the exception.
throw e;
}
finally
{
if (sessionKey != null)
{
sessionKey.Clear();
}
}
}
}
Este exemplo assume que um arquivo chamado "test.xml" existe no mesmo diretório do programa compilado. Ele também pressupõe que "test.xml" contém um "creditcard" elemento. Você pode colocar o XML a seguir em um arquivo denominado test.xml e usá-lo com esse exemplo.
<root>
<creditcard>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</creditcard>
</root>
Compilando o código
Para compilar este exemplo, você precisa incluir uma referência a System.Security.dll.
Inclua os namespaces a seguir: System.Xml, System.Security.Cryptography, e System.Security.Cryptography.Xml.
Segurança
Nunca armazene uma chave de criptografia simétrica em texto não criptografado ou transferência uma chave simétrica entre máquinas em texto não criptografado.Além disso, nunca armazene ou transferência a chave particular de um emparelhar de chaves assimétricas em texto não criptografado.Para obter mais informações sobre chaves de criptografia simétricas e assimétricas, consulte Gerando chaves de criptografia e descriptografia.
Nunca incorpore uma chave diretamente no seu código-fonte.Chaves incorporadas podem ser lido com com facilidade de um assembly usando o Desassemblador do MSIL (ILDASM.exe) ou abrindo o assembly em um editor de texto, sistema autônomo o bloco de notas.
Quando tiver concluído usando uma chave criptográfica, desmarcá-la da memória, definindo cada byte para zero ou chamando o Clear método da classe criptografia gerenciada. Chaves criptográficas, às vezes, podem ser lido da memória por um depurador ou ler de um disco rígido se o local da memória é paginado para disco.
Consulte também
Tarefas
Como: Decrypt elementos XML com teclas Asymmetric
Referência
System.Security.Cryptography.Xml