このシリーズの第1回では、XML暗号化とその基礎を成す構文と処理の概要を説明しました。そこでは、XML暗号化におけるさまざまなタグとそれぞれの使用法を、構造化データを安全に交換する単純な例を使って考察し、DOMに基づくXML暗号化でのJava APIの案を示し、Java (JCA/JCE) における暗号化の概要を簡潔に説明しました。
この第2回ではまず、XML暗号化を使用する例として、情報交換のシナリオの検討から始めます。
2つの企業間での情報交換のプロセスを考えてみましょう。一方はオンラインの書籍販売業者、もう一方は出版社です。書籍販売業者が書籍を仕入れたいときは、出版社に対して仕入れ注文を出します。出版社側の営業部門がこの注文を受け取って処理し、それを経理部門へ転送します。この2つの企業はXML文書の形式の情報を交換します。文書には保護する必要がある部分と保護しないで送信できる部分があるので、XML暗号化は文書の各部分を区別するセキュリティーを実施するにはぴったりの方法です。
支払情報は、書籍販売業者のセキュリティー・ポリシーに従って、経理部門だけに示されます。営業部門が取り出す必要があるのは、書籍の名前、その品目ID、そして注文数量だけになります。これらは機密情報ではないので、保護されないままにしておきます。経理部門は仕入れ注文の中の支払情報を、あらかじめ交換済みの共通鍵を使って取り出す必要があります。(XML暗号化は構造化情報の暗号化と復号化だけを対象にしており、鍵交換の特定のメソッドを制約するものではないことに注意してください。)このポリシーをマッピングしてXML暗号化を行うと、営業部門では支払情報が隠蔽され、経理部門では支払情報が開示されるようになります。
ここで文書ベースのセキュリティーという概念について少し考えてみるのも、役に立つかもしれません。このセキュリティー・アーキテクチャーを使うと、文書レベルでセキュリティーを実施することができます。保護セッションのコンテキストは、保護文書内に実質的に保持されます。与信済み当事者が文書を復号化するために必要とする可能性がある情報は、すべて文書内に用意されます。フレキシブルで存続時間が長い論理保護セッションが生成され、これによって多数の当事者が同一保護セッションの一部になることができます。Web ServicesのためのこれからのプロトコルであるBusiness Transaction Protocol (BTP --参考文献を参照) では、セッションのコンテキストをトランザクション文書内に保持するという同じ概念を使用します。これによってトランザクションの存続時間が長くなり、その柔軟性が高まります。
上記の出版社と書籍販売業者の間の保護データ交換シナリオの要件を実行できるように、
demoXmlEncApp (リスト1 を参照) というデモ・アプリケーション・クラスを作成しました。このクラスは、XML暗号化のサンプル実装のクラスXmlEncryption (リスト2 を参照) を使用します。
demoXmlEncApp クラスのmain メソッドは、まずsimulateBookSellersEnd メソッドを呼び出して書籍販売業者側の処理を実行します。このメソッドは仕入れ注文のXMLファイルであるOrder.xml (リスト3を参照) を読み込み、XML暗号化で指定されている3つの暗号化メソッド (つまりXMLファイル全体の暗号化、要素の暗号化、要素の内容の暗号化) のいずれかで、そこにある機密情報を暗号化します。次にXML暗号化ファイルの他に、暗号化に使用された鍵もディスクに保存します。
リスト 3. Order.xml
<?xml version="1.0"?>
<!-- This Listing provides the sample XML File that will be encrypted. -->
<purchaseOrder>
<Order>
<BookName>Soccer For Dummies</BookName>
<Id>123-958-74598</Id>
<Quantity>500</Quantity>
</Order>
<Payment>
<CardNo>4502-3456-3278-2011</CardNo>
<CardType>VISA</CardType>
<ValidDate>12-10-2004</ValidDate>
</Payment>
</purchaseOrder> |
ファイル交換と鍵交換のプロトコルはここでは触れていませんが、それらは適切なメソッドを介して出版社で使用可能になっている (たとえばXML暗号化ファイルと共通鍵は、それぞれHTTPと公開鍵暗号化アルゴリズムを介して交換される) ものとします。
main メソッドは、次にsimulatePublishersEnd メソッドを実行して出版社の役割を行います。このメソッドは営業部門が必要な情報を取り出し、受け取ったXMLファイルをコンソールに表示します。さらに、経理部門のために支払情報を復号化して、それをコンソールに表示します。
demoXmlEncApp クラスの中のsimulateBookSellersEnd 関数は、まずXmlEncryption オブジェクトをインスタンス化し、
XmlEncryption のさまざまな設定メソッドを呼び出して、次の属性を設定します。
-
clearDoc: 暗号化されるXMLファイル (リスト3 を参照) のDOMオブジェクト形式。 -
encKey: 暗号化に使用される鍵。 -
algoName: 暗号化アルゴリズムの名前。 -
keyName: 暗号鍵の名前。第1回の記事で説明したように、これはXML暗号化の際にKeyName要素の子テキスト・ノードの値になります。 -
encId:EncryptedDataタグに付けられる名前で、文書内で固有のもの。
demoXmlEncApp クラスのsimulateBookSellersEnd メソッドは、XML暗号化エンジン (XmlEncryption クラス) のメソッドを呼び出しますが、どのメソッドを呼び出すかはアプリケーションの起動時に渡されるコマンド・ラインの引数によって異なります。XML暗号化の主な処理エンジンであるXmlEncryptionクラスの内部の様子を見てみましょう。
XML暗号化APIの案の一部を、第1回の記事ですでに紹介しました。XMLファイル全体の暗号化を行うために、クラスXmlEncryption の中にencryptCompleteXmlFile というメソッドがあったことを思い出してください (第1回のリスト11 を参照)。ここでencryptCompleteXmlFile メソッドの他に次の2つのメソッドを追加して、異なるタイプのデータ (異なる暗号化粒度) の暗号化要求にサービスできるようにします。
- XMLファイルの中の特定の要素を暗号化するための
encryptElementOfXmlFile - XMLファイルの中の特定の要素の内容を暗号化するための
encryptElementContentOfXmlFile
書籍販売業者は、
XmlEncryption
クラスの中の次の3つのXML暗号化メソッドのいずれかを使用することにより、仕入れ注文の中の機密情報を保護することができます。
- XML文書全体を暗号化する。
- XMLファイルの中の要素を暗号化する。
- XMLファイルの中の要素の内容を暗号化する。
書籍販売業者はOrder.xml ファイル全体を暗号化してXML暗号化ファイルを生成し、これを出版社の営業部門へ送信することができます。これによるセキュリティーはエンドツーエンドの通信リンクの全体で得られますが、書籍販売業者のセキュリティー・ポリシーには違反しています。このポリシーでは、支払情報を、営業部門では隠蔽し、経理部門では明示することを要求しています。この場合には、営業部門によってXML文書全体が復号化されて支払情報が開示されてしまいます。したがってこの方法は適切な方法とは思えません。ただし、スーパー暗号化 (この記事で後述) を使用すれば実用的になります。
書籍販売業者がOrder.xml ファイル全体を暗号化する場合、クラスdemoXmlEncApp の中のsimulateBookSellersEnd 関数は、クラスXmlEncryption のパブリック・メソッドencryptCompleteXmlFile の呼び出しを生成します。
このメソッドは、まずgetString プライベート・メソッドを呼び出して、暗号化されるXMLファイルをストリング形式に直列化します。次に暗号化メソッドgetEncryptedData を呼び出し、この暗号化メソッドはBase 64でエンコードした暗号テキスト・ストリングを戻します。そして暗号テキスト・ストリングはgetCipherDataDoc プライベート・メソッドに渡されます。このメソッドは子としてCipherValue タグを持つCipherData タグを生成して戻しますが、そこではBase 64でエンコードされた暗号テキスト・ストリングが保持されています。同様にEncryptionMethod タグとds:KeyInfo タグが生成されます。続いてこれらの3つのタグ (つまりCipherData (子のCipherValue タグを持つ)、EncryptionMethod、およびds:KeyInfo) は、EncryptedData タグの子のタグとして追加されます。EncryptedData タグはDOM文書オブジェクトencDataObj に実際にロードされ、直列化されてsimulateBookSellersEnd メソッドに戻されます。
書籍販売業者はXMLファイルの支払情報の部分を経理部門の共通鍵を使って暗号化し、ファイルの内容のその他の部分は営業部門が見ることができるように暗号化しないでおくことができます。この処理ではOrder.xml file の中のPayment 要素の暗号化が行われます。クレジット・カード情報は、暗号化されるPayment 要素の子ノードにあるので保護されるようになります。セキュリティー要件では、決済の手段 (クレジット・カードや銀行小切手など) は、許可されていないユーザーには表示されないように隠蔽されなければならないので、Payment 要素の暗号化はその要件を満たします。
この場合、クラス
demoXmlEncApp
の中のsimulateBookSellersEnd 関数が、クラス
XmlEncryption
のパブリック・メソッドencryptElementOfXmlFile の呼び出しを生成します。プライベート・メソッドgetElement は要素ノードを戻し、続いてこの要素ノードは直列化されて暗号化され、CipherData タグが生成されます。このメソッドはプライベート・メソッドreplaceElement の呼び出しを行ってclearDoc 内のPayment 要素をEncryptedData 要素で置き換えることを除いては、EncryptedData タグ生成プロセスは前述の場合と同様です。置き換えが行われた後、clearDoc が直列化されて戻されます。
3. XML暗号化によるXMLファイルの中の要素の内容の暗号化
書籍販売業者が行使できる3つ目の暗号化オプションは、Order.xml の中のクレジット・カード番号だけを暗号化する方法です。要素の内容を暗号化するメソッドが呼び出され、このメソッドによりCardNo 要素のテキストの内容だけが暗号化されます。ここで大きな疑問が湧いてきます。要素の暗号化を使えば同じことができるのに、なぜ内容の暗号化を持ち出す必要があるのでしょう。どちらのメソッドを使うかは、文書のセキュリティー・ポリシーによって決まります。要素の内容は保護しておくが、要素名と属性を開示する必要性がある場合は、内容の暗号化が役に立ちます。
書籍販売業者がクレジット・カード番号だけを隠蔽したい場合は、Order.xml の中の要素CardNo のテキスト内容が暗号化されます。simulateBookSellersEnd メソッドがパブリック・メソッドencryptElementContentOfXmlFile を呼び出しますが、このパブリック・メソッドがencryptElementOfXmlFileメソッドと異なるのは、要素そのものではなく要素の内容に対して作用するということだけです。
出版社側がXML暗号化ファイルを受け取ると、復号化が必要になります。前述の3つの暗号化メソッドのいずれの場合も、復号化のメソッドはgetDecryptedData です。
demoXmlEncApp
の中のsimulateBookSellersEnd メソッドがXML暗号化ファイルをテキスト・ストリングに直列化して、それを復号化のためのgetDecryptedData メソッドに渡します。
getDecryptedData メソッドはEncryptedData のタグを識別して、Base 64でエンコードされた暗号値を抽出します。復号化に必要な情報 (暗号化アルゴリズムの名前、暗号化されているデータの型、暗号鍵の名前) はすべてXML暗号化のタグ内にあります。
注: XML暗号化仕様では、これらの情報がすべてXML暗号化のタグ内になければならない と規定されているわけではありません。これらの属性の有無はオプションです。アプリケーションはこれらの情報を他の手段でも指定することができますが、ここでのデモ・アプリケーションとサンプルのXML暗号化実装では、これらの情報はすべてXML暗号化のタグ内にあるものとします。
ここでgetDecryptedData メソッドは、鍵とアルゴリズムの名前をもとに復号鍵を生成します。次にこのメソッドは、抽出したBase 64でエンコードされた暗号値、復号鍵、およびアルゴリズム名を、Decrypt というメソッドに渡します (暗号方式を参照)。
Decrypt メソッドは、デコードして復号化したデータをテキスト・ストリングで戻します。このテキスト・ストリングはEncryptionData 要素の型属性に従って操作されます。このときの型属性は次のいずれかになります。
- 新規XMLファイルとしてディスクに保存されるXMLファイル全体
-
EncryptedDataタグに置き換わる要素 (これにより元のXMLファイルになる) -
EncryptedDataタグに置き換わる要素の内容 (これにより元のXMLファイルになる)
スーパー暗号化では、経理部門の共通鍵を使って支払情報を暗号化して、要素が暗号化されたXMLファイルを生成します。こうしてできたファイルは次に営業部門の共通鍵を使って完全に暗号化されて、スーパー暗号化XMLファイルになります。
XML暗号化仕様では、XML暗号化ファイルを再暗号化することができ、これがスーパー暗号化XMLファイルになります。しかしXML暗号化を使ってEncryptedData 要素またはEncryptedKey 要素の特定の子を暗号化することはできません。言い換えれば、EncryptedData 要素は別のEncryptedData 要素の親や子になれません。
XML暗号化仕様によれば、任意のデータ (たとえば .jpgイメージやWeb上の実際のもの) を暗号化することもできます。これはXMLファイル全体の暗号化とほとんど同じですが、唯一異なるのはEncryptedData 要素の型属性の値です (参考文献を参照)。
XML暗号化仕様には、必須およびオプションの暗号アルゴリズムとして次のものが記載されています。
- ブロック暗号化
- ストリーム暗号化
- 鍵転送
- 鍵合意
- 対称鍵ラップ
- メッセージ・ダイジェスト
- メッセージ認証
Base 64エンコード・アルゴリズム (参考文献を参照) も必須です。あらゆる暗号はXML文書に挿入する前にBase 64でエンコードしなければなりません。このデモンストレーションでは、SunJCE暗号化プロバイダーのTripleDESブロック暗号化アルゴリズムを使用しています。暗号化のモードは、ブロック・サイズが8バイトのCBC (暗号ブロック・チェイニング) です。
XmlEncryption
クラスはJCA/JCE暗号ライブラリを使用しますが、これは次のメソッドに実装されています。
-
getEncryptedData: このメソッドはテキスト・ストリングを受け入れ、TripleDESアルゴリズムを使ってそれを暗号化します。対称暗号化 (参考文献を参照) の場合は、暗号化される平文の他に暗号鍵が必要です。この鍵は、クラスXmlEncryptionのプライベート属性encKeyとして使用することができます。入力テキスト・ストリングがバイトの配列に変換されて埋め込みが行われます。暗号化にブロック暗号アルゴリズムを使用していますが、このアルゴリズムでは平文の各バイトが8バイトのブロックに入る必要があるため、最後の不完全なブロックにはいくつかの文字で埋め込みを行います。サンプル実装では、埋め込み用文字としてブランク・スペース (" ") を使用しています。
次にCipherクラス・オブジェクトを作成し、それを暗号化モードで開始します。そして初期設定ベクトル (IV) をバイト配列の形で抽出し、平文をブロック暗号化して、IVのバイトを暗号化されたデータのバイトの前に置きます。クラスXmlEncryptionのメソッドgetBase64Encodedを使用すると、結果のバイト配列はBase 64でエンコードされたストリングに変換された後に戻されます。 -
Decrypt: このメソッドは、基本的にはgetEncryptedDataメソッドと逆のものです。Base 64でエンコードされた暗号バイト配列を受け入れ、それをデコードして復号化し、平文に戻します。次にIVが実際の暗号バイト配列から分離されます。Cipherクラス・オブジェクトが作成され、復号モードで開始されます。次に暗号バイト配列が復号化され、復号化されたバイト配列がテキスト・ストリングとして戻されます。
ここでは、デモンストレーション用にTripleDESブロック暗号アルゴリズムだけをサポートしています。多少の変更を加えれば、AESなどの他のアルゴリズムも使用することができます。
この簡単な実装は、もっと大規模で複雑なビジネス・アプリケーションのセキュリティー・フレームワークとしてXML暗号化をどのように展開できるかを実証しています。
Simple Object Access Protocol (SOAP) (参考文献を参照) はXMLベースのデータ交換のための軽いプロトコルです。これによって、リモート・プロシージャー呼び出しと応答でのデータの交換が容易になります。これは分散およびリモート・アプリケーションで使われることを目的に設計されており、Web Servicesでの主要なコンポーネントです。SOAPではメッセージとその処理情報を入れるためのエンベロープが使用されます。このエンベロープの内容は機密の場合があるので、セキュリティーの問題に対処しなければなりません。XML暗号化は、この問題のシームレスなソリューションになります。
SOAP自体はXMLであり、XML暗号化を使った適切な方法で暗号化の問題を自由に処理することができます。たとえば、SOAP本体の全体を暗号化するか、または本体の一部を暗号化するかを決めることができます。一方、SOAPベースのWeb Servicesでのセキュリティーの実装方法の標準化を目的としたW3Cの試みとしてXML-SECがあります。現時点では、これにはXML暗号化は含まれていません。今後XML暗号化または同様の暗号化方法論がその一部に組み込まれることを期待しています。(訳注:現在は、WS-Security仕様が提案され、SOAPに対する暗号化の標準案としてOASISで議論されています)
第1回の記事ではXML暗号化の概要を説明し、それを使って安全なデータ交換を行う方法を検討しました。XML暗号化でのさまざまなタグの使用法を詳しく説明し、DOMを基にしたXML暗号化のためのJava APIの案を示しました。
この第2回では、XML暗号化の概念を使える典型的なデータ交換のシナリオを考察しました。また、XMLファイル全体の暗号化、XMLファイルの要素の暗号化、およびXML要素の内容の暗号化といったXML暗号化の各タイプも例を使って説明しました。さらに、復号化、スーパー暗号化、およびSOAPベースのWeb ServicesにおけるXML暗号化の概念のアプリケーションについても検討しました。
| ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|
| x-encrypt2/x-encrypt2_src.zip | 26.5KB | HTTP |
- XML暗号化に関するこの2回シリーズの記事のXML暗号化の方法を探る: 第1回 (developerworks 2002年3月、Bilal Siddiqui著) をお読みください。
- このデモンストレーション用の作業コード全体をダウンロードしてください。この記事の中で参照している次のコードがあります。
- Readme.txtには環境のセットアップ方法とデモの実行方法が記載されています。
- demoXmlEncApp.java (リスト1)
- XmlEncryption.java (リスト2)
- Order.xml (リスト3)
- AlgoNames.java
- CipherData.java
- EncryptedData.java
- EncryptionMethod.java
- GenericKeyInfo.java
- Transforms.java
- この記事の中で取り上げたW3C XML Encryption Specification Candidate Recommendation を調べてください。
- まだ開発中ですが、ビジネス・トランザクションのための柔軟なアーキテクチャーであるBusiness Transaction Protocol (BTP) を調査してください。
- 鍵交換のために設計されたプロトコルXML Digital Signature (XML-DSIG) をお読みください。
- 分散環境におけるデータ交換のためのプロトコルを定義しているSOAP仕様を調査してください。
- XMLに関する参考文献が、developerWorks XMLゾーン に多数あります。
-
IBM WebSphere Studio Application Developerをご覧ください。これは、J2EEアプリケーションの作成、テスト、および配置のための使いやすい統合開発環境で、DTDとスキーマからのXML文書の生成もサポートしています。
- XMLと関連テクノロジーの分野でIBM認定の開発者になる方法が、
IBM Certified Developer in XML and related technologies に記載されています。
Bilal SiddiquiはXMLのコンサルタントです。パキスタン、ラホールのUniversity of Engineering and Technologyで電子工学を学んだのち、1995年に産業制御システム向けのソフトウェア・ソリューションの設計を始めました。その後XMLに転向し、C++ のプログラミング経験を生かしてWebおよびWAPベースのXML処理ツール、サーバー・サイド構文解析ソリューション、およびサービス・アプリケーションの構築を行うようになりました。Bilalの連絡先はwap_monster@yahoo.com です。