방법: 대칭 키를 사용하여 XML 요소 암호화
System.Security.Cryptography.Xml 네임스페이스의 클래스를 사용하여 XML 문서 내의 요소를 암호화할 수 있습니다. XML 암호화를 이용하면 데이터 읽기가 쉽지 않기 때문에 이러한 걱정 없이 중요한 XML을 저장하거나 전송할 수 있습니다. 이 절차에서는 Rijndael이라는 AES(고급 암호화 표준) 알고리즘을 사용하여 XML 요소를 해독합니다.
이 절차를 통해 암호화된 XML 요소의 해독 방법에 대한 자세한 내용은 방법: 대칭 키를 사용하여 XML 요소 해독을 참조하십시오.
XML 데이터 암호화에 AES와 같은 대칭 알고리즘을 사용할 경우, XML 데이터 암호화 및 해독에 동일한 키를 사용해야 합니다. 이 절차의 예제에서는 암호화된 XML이 동일한 키를 사용하여 해독되고, 암호화 및 해독할 때 사용할 알고리즘 및 키에 동의한다고 가정합니다. 이 예제에서는 암호화된 XML 내에서 AES 키를 저장하거나 암호화하지 않습니다.
이 예제는 단일 응용 프로그램이 메모리에 저장된 세션 키나 암호에서 파생되어 강력하게 암호화된 키를 기반으로 데이터를 암호화해야 하는 경우에 적절합니다. 둘 이상의 응용 프로그램이 암호화된 XML 데이터를 공유해야 하는 경우에는 비대칭 알고리즘이나 X.509 인증서 기반의 암호화 체계를 사용하십시오.
대칭 키로 XML 요소를 암호화하려면
RijndaelManaged 클래스를 사용하여 대칭 키를 생성합니다. 이 키는 XML 요소를 암호화할 때 사용합니다.
Dim key As RijndaelManaged = Nothing Try ' Create a new Rijndael key. key = New RijndaelManaged()
RijndaelManaged key = null; try { // Create a new Rijndael key. key = new RijndaelManaged();
디스크에서 XML 파일을 로드하여 XmlDocument 개체를 만듭니다. XmlDocument 개체는 암호화할 XML 요소를 포함하고 있습니다.
' Load an XML document. Dim xmlDoc As New XmlDocument() xmlDoc.PreserveWhitespace = True xmlDoc.Load("test.xml")
// Load an XML document. XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load("test.xml");
XmlDocument 개체에서 지정된 요소를 찾아 암호화할 요소를 나타낼 새 XmlElement 개체를 만듭니다. 이 예제에서는 "creditcard" 요소가 암호화됩니다.
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementName)(0)
XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
EncryptedXml 클래스의 새 인스턴스를 만들고 XmlElement를 대칭 키를 사용하여 암호화하는 데 이 인스턴스를 사용합니다. EncryptData 메서드는 암호화된 요소를 암호화된 바이트 배열로 반환합니다.
Dim eXml As New EncryptedXml() Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, Key, False)
EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
EncryptedData 개체를 만들고 이를 XML 암호화 요소의 URL 식별자로 채웁니다. 해독할 때 이 URL 식별자를 통해 XML에 암호화된 요소가 있는지 알 수 있습니다. XmlEncElementUrl 필드를 사용하여 URL 식별자를 지정할 수 있습니다.
Dim edElement As New EncryptedData() edElement.Type = EncryptedXml.XmlEncElementUrl
EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl;
EncryptionMethod 개체를 만듭니다. 이 개체는 세션 키 생성에 사용되는 암호화 알고리즘의 URL 식별자로 초기화됩니다. EncryptionMethod 개체를 EncryptionMethod 속성으로 전달합니다.
Dim encryptionMethod As String = Nothing If TypeOf Key Is TripleDES Then encryptionMethod = EncryptedXml.XmlEncTripleDESUrl ElseIf TypeOf Key Is DES Then encryptionMethod = EncryptedXml.XmlEncDESUrl End If If TypeOf Key Is Rijndael Then Select Case Key.KeySize Case 128 encryptionMethod = EncryptedXml.XmlEncAES128Url Case 192 encryptionMethod = EncryptedXml.XmlEncAES192Url Case 256 encryptionMethod = EncryptedXml.XmlEncAES256Url End Select Else ' Throw an exception if the transform is not in the previous categories Throw New CryptographicException("The specified algorithm is not supported for XML Encryption.") End If edElement.EncryptionMethod = New EncryptionMethod(encryptionMethod)
string encryptionMethod = null; if (Key is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (Key is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } if (Key is Rijndael) { switch (Key.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { // Throw an exception if the transform is not in the previous categories throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
암호화된 요소 데이터를 EncryptedData 개체에 추가합니다.
edElement.CipherData.CipherValue = encryptedElement
edElement.CipherData.CipherValue = encryptedElement;
원래 XmlDocument 개체의 요소를 EncryptedData 요소로 바꿉니다.
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
예제
Imports System
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Module Program
Sub Main(ByVal args() As String)
Dim key As RijndaelManaged = Nothing
Try
' Create a new Rijndael key.
key = New RijndaelManaged()
' Load an XML document.
Dim xmlDoc As New XmlDocument()
xmlDoc.PreserveWhitespace = True
xmlDoc.Load("test.xml")
' Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", key)
Console.WriteLine("The element was encrypted")
Console.WriteLine(xmlDoc.InnerXml)
Decrypt(xmlDoc, key)
Console.WriteLine("The element was decrypted")
Console.WriteLine(xmlDoc.InnerXml)
Catch e As Exception
Console.WriteLine(e.Message)
Finally
' Clear the key.
If Not (key Is Nothing) Then
key.Clear()
End If
End Try
End Sub
Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementName As String, ByVal Key As SymmetricAlgorithm)
' Check the arguments.
If Doc Is Nothing Then
Throw New ArgumentNullException("Doc")
End If
If ElementName Is Nothing Then
Throw New ArgumentNullException("ElementToEncrypt")
End If
If Key Is Nothing Then
Throw New ArgumentNullException("Alg")
End If
''''''''''''''''''''''''''''''''''''''''''''''''''
' Find the specified element in the XmlDocument
' object and create a new XmlElemnt object.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementName)(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
''''''''''''''''''''''''''''''''''''''''''''''''''
' Create a new instance of the EncryptedXml class
' and use it to encrypt the XmlElement with the
' symmetric key.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim eXml As New EncryptedXml()
Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, Key, False)
''''''''''''''''''''''''''''''''''''''''''''''''''
' Construct an EncryptedData object and populate
' it with the desired encryption information.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim edElement As New EncryptedData()
edElement.Type = EncryptedXml.XmlEncElementUrl
' Create an EncryptionMethod element so that the
' receiver knows which algorithm to use for decryption.
' Determine what kind of algorithm is being used and
' supply the appropriate URL to the EncryptionMethod element.
Dim encryptionMethod As String = Nothing
If TypeOf Key Is TripleDES Then
encryptionMethod = EncryptedXml.XmlEncTripleDESUrl
ElseIf TypeOf Key Is DES Then
encryptionMethod = EncryptedXml.XmlEncDESUrl
End If
If TypeOf Key Is Rijndael Then
Select Case Key.KeySize
Case 128
encryptionMethod = EncryptedXml.XmlEncAES128Url
Case 192
encryptionMethod = EncryptedXml.XmlEncAES192Url
Case 256
encryptionMethod = EncryptedXml.XmlEncAES256Url
End Select
Else
' Throw an exception if the transform is not in the previous categories
Throw New CryptographicException("The specified algorithm is not supported for XML Encryption.")
End If
edElement.EncryptionMethod = New EncryptionMethod(encryptionMethod)
' 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)
End Sub 'Encrypt
Sub Decrypt(ByVal Doc As XmlDocument, ByVal Alg As SymmetricAlgorithm)
' 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
' Find the EncryptedData element in the XmlDocument.
Dim encryptedElement As XmlElement = Doc.GetElementsByTagName("EncryptedData")(0)
' If the EncryptedData element was not found, throw an exception.
If encryptedElement Is Nothing Then
Throw New XmlException("The EncryptedData element was not found.")
End If
' Create an EncryptedData object and populate it.
Dim edElement As New EncryptedData()
edElement.LoadXml(encryptedElement)
' Create a new EncryptedXml object.
Dim exml As New EncryptedXml()
' Decrypt the element using the symmetric key.
Dim rgbOutput As Byte() = exml.DecryptData(edElement, Alg)
' Replace the encryptedData element with the plaintext XML element.
exml.ReplaceData(encryptedElement, rgbOutput)
End Sub
End Module
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
namespace CSCrypto
{
class Program
{
static void Main(string[] args)
{
RijndaelManaged key = null;
try
{
// Create a new Rijndael key.
key = new RijndaelManaged();
// Load an XML document.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("test.xml");
// Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", key);
Console.WriteLine("The element was encrypted");
Console.WriteLine(xmlDoc.InnerXml);
Decrypt(xmlDoc, key);
Console.WriteLine("The element was decrypted");
Console.WriteLine(xmlDoc.InnerXml);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
// Clear the key.
if (key != null)
{
key.Clear();
}
}
}
public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key)
{
// Check the arguments.
if (Doc == null)
throw new ArgumentNullException("Doc");
if (ElementName == null)
throw new ArgumentNullException("ElementToEncrypt");
if (Key == null)
throw new ArgumentNullException("Alg");
////////////////////////////////////////////////
// Find the specified element in the XmlDocument
// object and create a new XmlElemnt object.
////////////////////////////////////////////////
XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
// Throw an XmlException if the element was not found.
if (elementToEncrypt == null)
{
throw new XmlException("The specified element was not found");
}
//////////////////////////////////////////////////
// Create a new instance of the EncryptedXml class
// and use it to encrypt the XmlElement with the
// symmetric key.
//////////////////////////////////////////////////
EncryptedXml eXml = new EncryptedXml();
byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
////////////////////////////////////////////////
// Construct an EncryptedData object and populate
// it with the desired encryption information.
////////////////////////////////////////////////
EncryptedData edElement = new EncryptedData();
edElement.Type = EncryptedXml.XmlEncElementUrl;
// Create an EncryptionMethod element so that the
// receiver knows which algorithm to use for decryption.
// Determine what kind of algorithm is being used and
// supply the appropriate URL to the EncryptionMethod element.
string encryptionMethod = null;
if (Key is TripleDES)
{
encryptionMethod = EncryptedXml.XmlEncTripleDESUrl;
}
else if (Key is DES)
{
encryptionMethod = EncryptedXml.XmlEncDESUrl;
}
if (Key is Rijndael)
{
switch (Key.KeySize)
{
case 128:
encryptionMethod = EncryptedXml.XmlEncAES128Url;
break;
case 192:
encryptionMethod = EncryptedXml.XmlEncAES192Url;
break;
case 256:
encryptionMethod = EncryptedXml.XmlEncAES256Url;
break;
}
}
else
{
// Throw an exception if the transform is not in the previous categories
throw new CryptographicException("The specified algorithm is not supported for XML Encryption.");
}
edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
// 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);
}
public static void Decrypt(XmlDocument Doc, SymmetricAlgorithm Alg)
{
// Check the arguments.
if (Doc == null)
throw new ArgumentNullException("Doc");
if (Alg == null)
throw new ArgumentNullException("Alg");
// Find the EncryptedData element in the XmlDocument.
XmlElement encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
// If the EncryptedData element was not found, throw an exception.
if (encryptedElement == null)
{
throw new XmlException("The EncryptedData element was not found.");
}
// Create an EncryptedData object and populate it.
EncryptedData edElement = new EncryptedData();
edElement.LoadXml(encryptedElement);
// Create a new EncryptedXml object.
EncryptedXml exml = new EncryptedXml();
// Decrypt the element using the symmetric key.
byte[] rgbOutput = exml.DecryptData(edElement, Alg);
// Replace the encryptedData element with the plaintext XML element.
exml.ReplaceData(encryptedElement, rgbOutput);
}
}
}
이 예제에서는 컴파일된 프로그램과 같은 디렉터리에 "test.xml" 파일이 있다고 가정합니다. 또한 "test.xml"에 "creditcard" 요소가 포함되고 있다고 가정합니다. 다음 XML을 test.xml 파일에 추가한 다음 이 예제에서 사용할 수 있습니다.
<root>
<creditcard>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</creditcard>
</root>
코드 컴파일
이 예제를 컴파일하려면 System.Security.dll에 대한 참조를 포함해야 합니다.
System.Xml, System.Security.Cryptography 및 System.Security.Cryptography.Xml 네임스페이스를 포함합니다.
보안
암호화 키를 일반 텍스트로 저장하거나 시스템 간의 키를 일반 텍스트로 전송하지 마십시오. 대신 보안 키 컨테이너를 사용하여 암호화 키를 저장합니다.
암호화 키 사용을 마쳤으면 각 바이트를 0으로 설정하거나 관리되는 암호화 클래스의 Clear 메서드를 호출하여 메모리에서 암호화 키를 지웁니다.
참고 항목
작업
참조
System.Security.Cryptography.Xml