방법: X.509 인증서로 XML 요소 암호화

System.Security.Cryptography.Xml 네임스페이스의 클래스를 사용하여 XML 문서 내의 요소를 암호화할 수 있습니다. XML 암호화는 데이터가 쉽게 읽힐 염려 없이 암호화된 XML 데이터를 교환하거나 저장할 수 있는 표준 방식입니다. XML 암호화 표준에 대한 자세한 내용은 http://www.w3.org/TR/xmldsig-core/에서 XML 암호화에 대한 W3C(World Wide Web 컨소시엄) 사양을 참조하십시오.

XML 암호화를 사용하여 암호화된 XML 데이터가 포함된 <EncryptedData> 요소의 문서나 XML 요소를 대체할 수 있습니다. <EncryptedData> 요소는 암호화 중에 사용된 키와 프로세스에 대한 정보가 들어 있는 하위 요소를 포함할 수 있습니다. XML 암호화에서는 한 문서가 여러 개의 암호화된 요소를 포함하고 한 요소가 여러 번 암호화될 수 있습니다. 이 절차의 코드 예제에서는 나중에 해독 과정에서 사용할 수 있는 다른 여러 하위 요소와 함께 <EncryptedData> 요소를 생성하는 방법을 보여 줍니다.

이 예제에서는 두 가지 키를 사용하여 XML 요소를 암호화합니다. Makecert.exe(인증서 작성 도구)를 사용하여 테스트용 X.509 인증서를 생성한 다음 이 인증서를 인증서 저장소에 저장합니다. 그런 다음 프로그래밍을 통해 인증서를 검색하고 이 인증서와 Encrypt 메서드를 사용하여 XML 요소를 암호화합니다. 내부적으로는 Encrypt 메서드가 별도의 세션 키를 만들고 이 키를 사용하여 XML 문서를 암호화합니다. 이 메서드는 세션 키를 암호화하고 이를 암호화된 XML과 함께 새 <EncryptedData> 요소 내부에 저장합니다.

XML 요소를 해독하려면 DecryptDocument 메서드만 호출하면 됩니다. 이 메서드는 저장소에서 X.509 인증서를 자동으로 검색하고 필요한 해독 작업을 수행합니다. 이 절차를 통해 암호화된 XML 요소의 해독 방법에 대한 자세한 내용은 방법: X.509 인증서로 XML 요소 해독을 참조하십시오.

이 예제는 여러 응용 프로그램에서 암호화된 데이터를 공유해야 하거나 단일 응용 프로그램에서 실행 시점 사이에 암호화된 데이터를 저장해야 하는 경우에 적합합니다.

X.509 인증서로 XML 요소를 암호화하려면

  1. 테스트용 X.509 인증서를 생성하고 이를 로컬 사용자 저장소에 보관하려면 Makecert.exe(인증서 작성 도구)를 사용합니다. 교환 키를 생성하고 이 키를 내보낼 수 있게 해야 합니다. 다음 명령을 실행합니다.

    makecert -r -pe -n "CN=XML_ENC_TEST_CERT" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my
    
  2. X509Store 개체를 만들고 이를 초기화하여 현재 사용자 저장소를 엽니다.

    Dim store As New X509Store(StoreLocation.CurrentUser)
    
    X509Store store = new X509Store(StoreLocation.CurrentUser);
    
  3. 읽기 전용 모드로 저장소를 엽니다.

    store.Open(OpenFlags.ReadOnly)
    
    store.Open(OpenFlags.ReadOnly);
    
  4. 저장소의 모든 인증서와 함께 X509Certificate2Collection을 초기화합니다.

    Dim certCollection As X509Certificate2Collection = store.Certificates
    
    X509Certificate2Collection certCollection = store.Certificates;
    
  5. 저장소의 인증서를 열거하고 알맞은 이름의 인증서를 찾습니다. 이 예제에서 인증서 이름은 "CN=XML_ENC_TEST_CERT"입니다.

    Dim cert As X509Certificate2 = Nothing
    
    ' Loop through each certificate and find the certificate 
    ' with the appropriate name.
    Dim c As X509Certificate2
    For Each c In certCollection
        If c.Subject = "CN=XML_ENC_TEST_CERT" Then
            cert = c
    
            Exit For
        End If
    Next c
    
    X509Certificate2 cert = null;
    
    // Loop through each certificate and find the certificate 
    // with the appropriate name.
    foreach (X509Certificate2 c in certCollection)
    {
        if (c.Subject == "CN=XML_ENC_TEST_CERT")
        {
            cert = c;
    
            break;
        }
    }
    
  6. 인증서를 찾은 후 저장소를 닫습니다.

    store.Close()
    
    store.Close();
    
  7. 디스크에서 XML 파일을 로드하여 XmlDocument 개체를 만듭니다. XmlDocument 개체는 암호화할 XML 요소를 포함하고 있습니다.

    Dim xmlDoc As New XmlDocument()
    
    XmlDocument xmlDoc = new XmlDocument();
    
  8. XmlDocument 개체에서 지정된 요소를 찾아 암호화할 요소를 나타낼 새 XmlElement 개체를 만듭니다. 이 예제에서는 "creditcard" 요소가 암호화됩니다.

            Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
    
    
    XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
    
  9. EncryptedXml 클래스의 새 인스턴스를 만들고 이를 사용하여 지정된 요소를 X.509 인증서와 함께 암호화합니다. Encrypt 메서드는 암호화된 요소를 EncryptedData 개체로 반환합니다.

    Dim eXml As New EncryptedXml()
    
    ' Encrypt the element.
    Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
    
    EncryptedXml eXml = new EncryptedXml();
    
    // Encrypt the element.
    EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);
    
  10. 원래 XmlDocument 개체의 요소를 EncryptedData 요소로 바꿉니다.

    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    
  11. XmlDocument 개체를 저장합니다.

    xmlDoc.Save("test.xml")
    
    xmlDoc.Save("test.xml");
    

예제

Imports System
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates



Module Program

    Sub Main(ByVal args() As String)
        Try
            ' Create an XmlDocument object.
            Dim xmlDoc As New XmlDocument()
            ' Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")

            ' Open the X.509 "Current User" store in read only mode.
            Dim store As New X509Store(StoreLocation.CurrentUser)
            store.Open(OpenFlags.ReadOnly)
            ' Place all certificates in an X509Certificate2Collection object.
            Dim certCollection As X509Certificate2Collection = store.Certificates
            Dim cert As X509Certificate2 = Nothing

            ' Loop through each certificate and find the certificate 
            ' with the appropriate name.
            Dim c As X509Certificate2
            For Each c In certCollection
                If c.Subject = "CN=XML_ENC_TEST_CERT" Then
                    cert = c

                    Exit For
                End If
            Next c
            If cert Is Nothing Then
                Throw New CryptographicException("The X.509 certificate could not be found.")
            End If

            ' Close the store.
            store.Close()
            ' Encrypt the "creditcard" element.
            Encrypt(xmlDoc, "creditcard", cert)

            ' 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)
        End Try

    End Sub 'Main


    Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal Cert As X509Certificate2)
        ' 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 Cert Is Nothing Then
            Throw New ArgumentNullException("Cert")
        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

        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' Create a new instance of the EncryptedXml class 
        ' and use it to encrypt the XmlElement with the 
        ' X.509 Certificate.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        Dim eXml As New EncryptedXml()

        ' Encrypt the element.
        Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' Replace the element from the original XmlDocument
        ' object with the EncryptedData element.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    End Sub
End Module
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Security.Cryptography.X509Certificates;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            // Create an XmlDocument object.
            XmlDocument xmlDoc = new XmlDocument();

            // Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");

            // Open the X.509 "Current User" store in read only mode.
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);

            // Place all certificates in an X509Certificate2Collection object.
            X509Certificate2Collection certCollection = store.Certificates;

            X509Certificate2 cert = null;

            // Loop through each certificate and find the certificate 
            // with the appropriate name.
            foreach (X509Certificate2 c in certCollection)
            {
                if (c.Subject == "CN=XML_ENC_TEST_CERT")
                {
                    cert = c;

                    break;
                }
            }

            if (cert == null)
            {
                throw new CryptographicException("The X.509 certificate could not be found.");
            }

            // Close the store.
            store.Close();

            // Encrypt the "creditcard" element.
            Encrypt(xmlDoc, "creditcard", cert);

            // 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);
        }

    }

    public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, X509Certificate2 Cert)
    {
        // Check the arguments.  
        if (Doc == null)
            throw new ArgumentNullException("Doc");
        if (ElementToEncrypt == null)
            throw new ArgumentNullException("ElementToEncrypt");
        if (Cert == null)
            throw new ArgumentNullException("Cert");

        ////////////////////////////////////////////////
        // 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");

        }

        //////////////////////////////////////////////////
        // Create a new instance of the EncryptedXml class 
        // and use it to encrypt the XmlElement with the 
        // X.509 Certificate.
        //////////////////////////////////////////////////

        EncryptedXml eXml = new EncryptedXml();

        // Encrypt the element.
        EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);

        ////////////////////////////////////////////////////
        // Replace the element from the original XmlDocument
        // object with the EncryptedData element.
        ////////////////////////////////////////////////////
        EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    }
}

이 예제에서는 컴파일된 프로그램과 같은 디렉터리에 "test.xml" 파일이 있다고 가정합니다. 또한 "test.xml"에 "creditcard" 요소가 포함되고 있다고 가정합니다. 다음 XML을 test.xml 파일에 추가한 다음 이 예제에서 사용할 수 있습니다.

<root>
    <creditcard>
        <number>19834209</number>
        <expiry>02/02/2002</expiry>
    </creditcard>
</root>

코드 컴파일

보안

이 예제에서 사용한 X.509 인증서는 테스트 전용입니다. 응용 프로그램에서는 신뢰할 수 있는 인증 기관에서 생성한 X.509 인증서를 사용하거나 Microsoft Windows Certificate Server에서 생성한 인증서를 사용해야 합니다.

참고 항목

작업

방법: X.509 인증서로 XML 요소 해독

참조

System.Security.Cryptography.Xml

기타 리소스

XML 암호화 및 디지털 서명