次の方法で共有


方法 : 共通キーで XML 要素を復号化する

更新 : 2007 年 11 月

System.Security.Cryptography.Xml 名前空間のクラスを使用して、XML ドキュメント内の要素を暗号化できます。XML 暗号化により、細心の注意を要する XML を格納または転送でき、データを簡単に読み取られる心配はありません。このコード例では、Rijndael とも呼ばれる AES (Advanced Encryption Standard) アルゴリズムを使用して XML 要素を復号化します。

この手順を使用して XML 要素を暗号化する方法については、「方法 : 共通キーで XML 要素を暗号化する」を参照してください。

AES のような対称アルゴリズムを使用して XML データを暗号化する場合は、同じキーを使用して XML データの暗号化と復号化を行う必要があります。この手順の例では、暗号化された XML が同じキーを使用して暗号化されたこと、また使用するアルゴリズムとキーに暗号化および復号化パーティが同意することを前提としています。この例は、暗号化された XML 内の AES キーを格納または暗号化しません。

この例は、1 つのアプリケーションがメモリに格納されたセッション キーに基づいて、またはパスワードから派生した厳密な暗号キーに基づいて、データを暗号化する場合に適しています。2 つ以上のアプリケーションで暗号化された XML データを共有する必要がある場合は、非対称アルゴリズムまたは X.509 証明書に基づく暗号化方式を使用することを検討してください。

共通キーで XML 要素を複合化するには

  1. 方法 : 共通キーで XML 要素を暗号化する」で説明した手法を使用して、前に生成されたキーで XML 要素を暗号化します。

  2. 暗号化された XML を含む XmlDocument オブジェクトで <EncryptedData> 要素 (XML 暗号化標準で定義された) を検索し、その要素を表す新しい XmlElement オブジェクトを作成します。

    Dim encryptedElement As XmlElement = Doc.GetElementsByTagName("EncryptedData")(0)
    
             XmlElement encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
    
  3. 前に作成した XmlElement オブジェクトから生の XML データを読み込んで、EncryptedData オブジェクトを作成します。

    Dim edElement As New EncryptedData()
    edElement.LoadXml(encryptedElement)
    
             EncryptedData edElement = new EncryptedData();
                edElement.LoadXml(encryptedElement);
    
  4. 新しい EncryptedXml オブジェクトを作成し、それを使用して、暗号化で使われたのと同じキーを使用している XML データを復号化します。

    Dim exml As New EncryptedXml()
    
    
    ' Decrypt the element using the symmetric key.
    Dim rgbOutput As Byte() = exml.DecryptData(edElement, Alg)
    
             EncryptedXml exml = new EncryptedXml();
    
    
                // Decrypt the element using the symmetric key.
                byte[] rgbOutput = exml.DecryptData(edElement, Alg);
    
  5. XML ドキュメント内で、暗号化された要素を新たに暗号化されたプレーンテキスト要素に置き換えます。

    exml.ReplaceData(encryptedElement, rgbOutput)
    
             exml.ReplaceData(encryptedElement, rgbOutput);
    

使用例

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" 要素が含まれていることも前提としています。test.xml という名前のファイルに次の XML を配置し、その XML をこの例と共に使用できます。

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

コードのコンパイル方法

セキュリティ

プレーンテキストに暗号化キーを格納したり、マシン間でプレーンテキストのキーを転送したりしないでください。

対称暗号化キーの使用が終了したら、各バイトをゼロに設定するか、暗号マネージ クラスの Clear メソッドを呼び出して、メモリからこのキーを消去してください。

参照

処理手順

方法 : 共通キーで XML 要素を暗号化する

参照

System.Security.Cryptography.Xml

その他の技術情報

XML 暗号化と XML デジタル署名