1.公開鍵でXML文書を暗号化する(C#)

 .NET Frameworkを使って、XML文書をRSA公開鍵で暗号化する方法を説明します。
ここでは、共通鍵や対象鍵といった表現はせず、「秘密鍵」(Secret Key)に統一します。また、公開鍵(非対称鍵)方式の鍵は、「公開鍵」「雌雄k儀」といい混乱しないようにします。

1.1 概要

 関連の名前空間は以下のとおりです。

  • System.Xml
    XML文書を扱うためのAPIを備えています。
  • System.Security.cryptography
    データの安全なエンコーディングやデコーディング、およびハッシュ演算、乱数生成、メッセージ認証などの操作を含む、暗号サービスが提供されます。
  • System.Security.cryptography.Xml
    XML デジタル署名の作成と検証をサポートするクラスを含んでいます。この名前空間のクラスは、W3C 勧告『XML-Signature Syntax and Processing』(http://www.w3.org/TR/xmldsig-core/)が実装されています。
 大まかな手順は、以下のとおりです。
  • 署名されるXML文書をロードする。
  • 暗号化の鍵を準備する。
  • 暗号化するエレメントを指定する。
  • 暗号化する。
  • 暗号化の情報を作成する。
  • XML文書を変更する。
 なお、暗号化される文書は以下のようなものです。(original.xmlとして利用するものです。)
<root>
    <creditcard>
        <number>19834209</number>
        <expiry>02/02/2002</expiry>
    </creditcard>
</root>


1.2 暗号化されるXML文書をロードする

 まず、暗号化されるXML文書をロードします。
 以下にコードを記します。
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

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

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

1.3 暗号化の鍵を準備し暗号化する

 公開鍵(非対称鍵)は、秘密鍵(対称鍵)を暗号化するのに使います。秘密鍵は、XML文書のエレメントを暗号化する鍵です。
 以下に、コードを記します。
            // キーコンテナを生成
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";

            // RSA公開鍵を生成
            // この鍵で秘密鍵を暗号化する
            RSACryptoServiceProvider rsaKey =
                  new RSACryptoServiceProvider(cspParams);

            // 暗号化するエレメントを探し出す。
            XmlElement elementToEncrypt =
                  xmlDoc.GetElementsByTagName("creditcard")[0] as XmlElement;
            // XmlExceptionが見つかったことの確認が必要

            // EncryptedXmlインスタンスを生成
            EncryptedXml eXml = new EncryptedXml();

            // 暗号化の256bit Rijndael鍵を生成
            sessionKey = new RijndaelManaged();
            sessionKey.KeySize = 256;

            // 生成した秘密鍵で暗号化する
            byte[] encryptedElement =
                    eXml.EncryptData(elementToEncrypt, sessionKey, false);
 Rijndael暗号化はAES暗号化とも呼ばれる暗号化アルゴリズムです。

1.4 <EncryptedData>を作成する

 <EncryptedData>オブジェクトを作成し暗号化の情報を挿入します。
 以下にコードを記します。
            // <EncryptedData>オブジェクトを生成
            EncryptedData edElement = new EncryptedData();
            edElement.Type = EncryptedXml.XmlEncElementUrl;
            edElement.Id = EncryptionElementID;

            edElement.EncryptionMethod =
                  new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
            // 秘密鍵を暗号化してこのエレメントに含める
            EncryptedKey ek = new EncryptedKey();

            // XML文書を暗号化した秘密鍵を公開鍵で暗号化し鍵情報とする
            byte[] encryptedKey =
                  EncryptedXml.EncryptKey(sessionKey.Key, rsaKey, false);
            ek.CipherData = new CipherData(encryptedKey);
            ek.EncryptionMethod =
                  new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);

            // DataReferenceエレメントを生成する。
            // このエレメントを使ってXML文書に<EncryptedData>を
            // 追加する。
            // XML文書に複数の<EncryptedData>を含められる。
            DataReference dRef = new DataReference();

            // EncryptedData URIを指定する。
            dRef.Uri = "#EncryptedElement1";

            // DataReferenceに暗号化のキーを挿入する。
            // これにより、<EncryptedData>にキーが追加される。
            ek.AddReference(dRef);

            // 鍵情報エレメントにRSA鍵の名前を入れる。
            edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));

            // KeyInfoエレメントを生成する。
            edElement.KeyInfo = new KeyInfo();

            // KeyInfoNameエレメントを生成する。
            KeyInfoName kin = new KeyInfoName();

            // 鍵の名前を指定する。
            kin.Value = "rsaKey";
  つづく...


(記載の会社名および製品名は、各社の登録商標および商標です。)