現在のところ、トランスポート層セキュリティー (TLS) が、インターネットにおける保護通信のデ・ファクト・スタンダードとなっています。TLSは、よく知られたSecure Socket Layer (SSL) に準拠したエンドツーエンドのセキュリティー・プロトコルです。SSLは、もともとNetscapeで設計されたものであり、そのバージョン3.0に対して、TLSを設計中のInternet Engineering Task Force (IETF) が後に手を加えたものです。これは、非常に安全性と信頼性の高いプロトコルであり、2者間のエンドツーエンド・セキュリティー・セッションを提供します。XML暗号化は、SSL/TLSを置き換えることを意図したものではありません。むしろ、SSLではカバーし切れないセキュリティー要件のためのメカニズムを提供するためのものです。SSLで対応できないこととして、以下に示す2つの重要な点があります。
- 交換するデータの一部を暗号化すること
- 2者以上での保護セッション
XML暗号化を使用した場合、どの通信者も、他者との間で保護状態または無保護状態を保つことができます。1つの文書の中で、保護データと無保護データの両方を交換できます。たとえば、ある保護機能付きチャット・アプリケーションがあるとします。それには、複数のチャット・ルームが含まれており、各チャット・ルームには複数の人が関係しています。チャット・パートナー相互の間ではXML暗号化ファイルを交換できますが、あるチャット・ルームのデータは、それ以外のチャット・ルームからは見えないようになっています。
XML暗号化では、XMLデータと非XMLデータ (バイナリー・データなど) を処理できます。以下に、XML暗号化によって保護された簡単なデータ交換の例を示します。セキュリティー要件を少しずつ複雑にしながら、XML暗号化スキーマとそのさまざまな要素の使い方について説明します。
リスト1 に示すXMLファイルを、ある出版会社に送るとします。このファイルには、購入したい本についての詳細なデータが含まれています。さらに、支払いに使用するクレジット・カードの情報も含まれています。当然、このような個人情報には保護通信を使用したいと思うことでしょう。1つの方法は、通信の全体を保護するSSLを使用することです。別の方法は、XML暗号化を使用することです。すでに述べたように、XML暗号化はSSL/TLSに代わるものではありません。通信の全体を保護する必要のあるアプリケーションなら、SSLを使用することでしょう。しかし、保護通信と無保護通信を組み合わせる (データの一部は保護した状態で交換し、それ以外の部分は元のまま交換する) ことの必要なアプリケーションの場合は、XML暗号化が最善です。
リスト1. 暗号化するサンプルXMLファイル
<purchaseOrder>
<Order>
<Item>book</Item>
<Id>123-958-74598</Id>
<Quantity>12</Quantity>
</Order>
<Payment>
<CardId>123654-8988889-9996874</CardId>
<CardName>visa</CardName>
<ValidDate>12-10-2004</ValidDate>
</Payment>
</purchaseOrder>
|
注: リスト1 のXMLファイルは、意図的に簡単なものにしてあります。それにより、暗号化の問題に注意を集中できます。共同コマースやWeb Servicesでの実際のXMLファイルは、構造としては似たようなものですが、もっと冗長です。WSDL (Webサービス記述言語) およびSOAP (Simple Object Access Protocol) は、B2B統合でしばしば使用されるXMLベースの文法です。WSDLでもSOAPでも、XML暗号化を使用することによって、企業全体にわたる保護通信を提供できます。詳細については、W3Cのサイトをご覧ください (参考文献を参照)。
XML暗号化には、さまざまなオプションがあります。リスト2、リスト3、およびリスト4 に、それぞれ異なる暗号化の結果を示します。1つずつ詳しく見てみましょう。
リスト2 は、リスト1 のXML文書全体を暗号化した場合のXML暗号化ファイルです。<CipherData> と<CipherValue> のタグに注目してください。<CipherValue> タグの内容が、実際の暗号化データです。CipherData 要素は、EncryptedData 要素の中に含まれています。EncryptedData 要素には、暗号化に使用されるXML名前空間が含まれています。たとえば、暗号化前の元のデータはXMLであり、Internet Assigned Numbers Authority (IANA) によるXMLの公式の型定義は、http://www.isi.edu/in-notes/iana/assignments/media-types/text/xmlです。このことは、Type 属性の値に示されています。XML暗号化では、RTF、PDF、JPGなど、広く使用されているさまざまなデータ形式に関して、IANAによる型定義が使用されます。詳しくは、対応するWebサイトをご覧ください (参考文献を参照)。特別なアプリケーション・データ型 (各企業のコンテンツ・マネージメント・システムに属する独自のDTDやXSDなど) の場合は、それをEncryptedData 要素のType 属性に指定できます。もう1つの属性xmlnsは、XMLデータの暗号化に使用したXML暗号化名前空間を指定します。
リスト1 のうち、1つの要素 (たとえばPayment 要素) だけを暗号化したいと思うかもしれません。その結果を、リスト3 に示します。リスト2 とリスト3 を比較すると、次のような違いがあります。
- リスト2 に含まれるのはXML暗号化のスキーマだけですが、リスト3 にはXML暗号化とリスト1 の元データの要素とが混在しています。リスト3 の場合、XML暗号化データはユーザーのXMLの内部に埋め込まれています。
-
リスト3 でも、
<EncryptedData>にType属性が指定されていますが、その値はhttp://www.w3.org/2001/04/xmlenc#Elementです。IANA型は使用されていません。その代わり、XML暗号化で指定される型が使用されています。 - 特に末尾の #Elementに注目してください。これは、EncryptedDataが1つの要素を表すことを意味しています。
リスト4 は、リスト1 に含まれる1つの要素CardId の内容だけを暗号化した結果です。この場合、Type 属性値にはhttp://www.w3.org/2001/04/xmlenc#Contentを使用しています。内容だけを暗号化する場合には、この値を使用します。
では、JPEGファイルなどをXML暗号化によって送信する場合は、どうなるのでしょうか? その典型的な例を、リスト5 に示します。JPEGファイルは、そのバイト・シーケンスを暗号化した上で、CipherValue 要素の内容として含められています。リスト2 とリスト5 の違いは、1つしかありません。それは、EncryptedData 要素のType 属性です。リスト5 には、JPEG形式に対応するIANA型が示されています。同じような方法でIANAの値を指定することによって、任意の形式を暗号化できます。IANAのWebサイトをご覧ください (参考文献を参照)。
リスト1~5は暗号化の例ですが、鍵がなくては使い物になりません (この後のコラム「公開鍵、私有鍵、および共通鍵」を参照)。XML暗号化で鍵に関連する問題は、次の2つの部分に分けられます。
- 鍵の交換 (非対称暗号化)
- 以前に交換された鍵の使用 (対称暗号化)
こうしてユーザーは鍵を交換し、その後それを使用できます。
このシナリオでは、通信の一方の側がその公開鍵を相手に送ります。相手は、その公開鍵を使用して、自分の共通鍵を暗号化します。このデータ交換の様子をリスト6 (要求) とリスト7 (応答) に示します。通信の一方の側がImranで、相手がAliであるとしましょう。Imranは、公開鍵交換要求を初期化し、その公開鍵をKeyValueという要素に入れて送ります。属性CarriedKeyName は、送信する鍵の名前を表します。この構造のルート要素はEncryptedKey であり、それにはds:KeyInfo 要素とds:KeyValue 要素が含まれます。
ds:KeyInfo 要素とds:KeyValue 要素は、XMLディジタル・シグニチャー (ds:) 名前空間に属しています。XML暗号化は、鍵の交換に関してはXMLディジタル・シグニチャーの仕様に完全に依存しています。そのため、<ds:EncryptedKey> と<ds:KeyValue> は、いずれもXMLディジタル・シグニチャー名前空間に属しています。リスト7 は、Aliが送る応答です。リスト7 の中のCipherValue 要素の内容は、新たに生成された共通鍵をImranの公開鍵によって暗したものです。
リスト6とリスト7をよく見ると、要求と応答の両方にEncryptedKey 要素が含まれていることがわかります。EncryptedKey 要素の中のds:KeyInfo 要素とds:KeyValue 要素によって、公開鍵が送信されます (リスト6)。一方、EncryptedKey 要素の中のCipherData 要素とCipherValue 要素 (リスト7) によって、共通鍵 (を暗号化したもの) が送信されます。さらに、EncryptedKey 要素には、常にCarriedKeyName 属性が含まれており、送信され名前がそれによって指定されます。
前のセクションでは、共通鍵を交換しました。ここでは、その鍵を使用してデータを暗号化します。Imranがリスト7 への応答としてXMLメッセージ (リスト8) を送信するとします (リスト7 には、"Imran Ali" という名前の暗号化された共通鍵が含まれていることに注意)。Imranは、自分の (Imranの) 私有鍵を使ってこの共通鍵を暗号化解除します (Aliは共通鍵をImranの公開鍵を使って暗号化しました)。Imranは、この共通鍵を使用し、
リスト8 のCipherValue 要素中にそれを入れることによって、Aliに送りたいデータを暗号化することができます。
リスト8 のds:KeyInfo 要素の中には、KeyName 要素が含まれています。この組み合わせにより、データ暗号化のためにImranが使用した鍵の名前が参照されます。
図1に、保護データ交換でのXMLファイル交換の様子を示します。
図1. XML暗号化による鍵およびデータの交換のシーケンス
リスト5 および7 において、CipherData 要素はEncryptedData 要素またはEncryptedKey 要素の中に指定できます。
CipherData 要素は、暗号化されたデータ (EncryptedData 要素の中に指定した場合) または暗号化された鍵 (EncryptedKey 要素の中に指定した場合) を参照するために使用しています。リスト5 とリスト7 の両方において、CipherData 要素の中に、実際の暗号化データを含むCipherValue 子要素が含まれています。
さらには、外部の暗号化データまたは暗号化鍵も参照できます。つまり、実際の暗号化データまたは暗号化鍵が、XML暗号化ファイルの中ではなく、どこか別の場所 (おそらくインターネット上のどこか) にあるという場合です。その場合には、CipherData の中でCipherValue 子要素の代わりにCipherReference を使用します。実際の暗号化データは、URIによって参照します。リスト9 をご覧ください。
リスト10 は、外部XMLファイルを参照する別の方法を示すものです。ここでは、URIの指す外部ファイルの一部分だけを参照しています。
CipherReference 要素の中にTransforms 子要素が含まれています。このTransforms 要素には、それぞれ単一のXPath要素を内容とするTransform 要素をいくつか含めることができます。このXPath要素には、外部XML文書の特定のノードを参照するXPath式を指定します。
ここまでで、XML暗号化ファイルを作成し、暗号化データを交換する方法を見てきました。次に、XML暗号化のためのJava APIの案と、その実装例を示します。そのために、DOMを使用することにします。
このDOM実装は、一群のクラスで構成されます (リスト11~16)。XmlEncryptionクラス (リスト11) は、それ以外のクラスのラッパーであり、APIのユーザーが実際に必要とするのはこのクラスだけです。その内部では、その他のクラスの機能が使用されています。
リスト11 は、XML暗号化ファイル全体を生成するラッパー・クラスです。
リスト12 は、EncryptedData 要素を作成します。
リスト13 は、EncryptionMethod 要素を作成します。
リスト14 は、KeyInfo 要素を作成します。
リスト15 は、CipherData要素を作成します。
リスト16 には、アルゴリズムの名前 (静的整数) とそれに対応する名前空間 (ストリング) が含まれています。
XmlEncryption クラス (リスト11) には、さまざまなpublic get/setメソッドが含まれています。ユーザーは、setメソッドを呼び出すことによって、次のような暗号化パラメーターを指定します。
- 暗号化するファイルの名前
- 結果出力先のXML暗号化ファイルの名前
- 暗号化のアルゴリズムの名前
- 暗号化のために使用する鍵の名前
-
<EncryptedData>構造の識別用ID
main () メソッドでXmlEncryption クラスを使う方法については、すでに示しました (リスト11)。main () メソッドでは、このクラスのインスタンスを作成します。そのコンストラクターではDOMのインスタンスを生成し、基本となるクラスのすべてが同じオブジェクトを使用するようにします。
この実装でサポートされているのは、リスト2 の場合のようなファイル全体の暗号化だけです。これはEncryptCompleteXmlFile () メソッドによって実行されます。そのメソッドの中では、次のメソッドが順に呼び出されます。
-
GetEncryptedDataDoc()がEncryptedDataクラス (リスト12) のオブジェクトを戻します。それには、EncryptedData要素の構造が含まれます。 -
GetEncryptionMethodDoc()が、EncryptionMethod要素に対応するXML構造を含むDocumentオブジェクトを戻します。GetEncryptionMethodDoc()は、EncryptionMethodクラス (リスト13) を使用してXMLを作成します。 -
GetKeyInfoDoc()が、Documentオブジェクトを戻します。それには、KeyInfo要素に対応するXML構造が含まれます。GetKeyInfoDoc()は、GenericKeyInfoクラス (リスト14) のオブジェクトを使用してXMLを作成します。このクラスには、最低限必要な機能しかありません (KeyName要素とKeyValue要素のサポート)。それで、機能全体を提供するため、GenericKeyInfoクラスから継承することになります。それには、X509証明書、PGPデータなどのサポートが含まれています。 -
ReadFile()によって、暗号化するデータ (XMLファイル全体) を取り出します。 - 今のところ、
GetEncryptedData()は何もしません。このメソッドは、このシリーズの第2回の記事で実装します。これは、ステップ4で取り出したXMLデータの暗号化形式を作成するためにサポートされています。使用する暗号化ストラテジーについては、最後のセクション (「Java Cryptographic Architecture」) で簡単に説明します。 -
GetCipherDataDoc()は、暗号化データを引き数とし、CipherData要素を含むDocumentオブジェクトを戻します。GetCipherDataDoc()は、CipherDataクラス (リスト12) のオブジェクトを使用することによってXMLを作成します。 - 最後に、
EncryptedData(リスト15) のオブジェクトのaddChild()メソッドを3回呼び出しています。それぞれステップ2、3、および6のDocumentオブジェクトを引き数に指定し、それらをその親である<EncryptedData>構造に追加します。 -
SaveEncryptedFile()によって、XML暗号化ファイル全体を保存します。
AlgoNames (リスト16) は、XML暗号化で必要な名前空間宣言を指定するだけのヘルパー・クラスです。
XmlEncryption クラス (リスト11) は、サーバー・サイド・コンポーネントとしても使用できます。このシリーズの第2回では、内部で独立して使用する方法とサーバー・サイド・アプリケーションとして使用する方法を示します。
ここで開発したクラスは、DOMベースのXMLオーサリングを実行するだけです。実際には、暗号化機能の実装も必要になります。ここで、暗号化サポートのためのストラテジーを構成することにします。そのためには、Java Cryptographic Architecture (JCA) について調べる必要があります。
Java Cryptographic Architecture (JCA)
Javaには、完全に揃った暗号化のサポートが含まれています。J2SEの中には、そのためのパッケージがいくつか含まれており、それによって、アクセス制御、シグニチャー、証明書、鍵ペア、鍵の保管、およびメッセージ・ダイジェストなど、セキュリティー・アーキテクチャーの主要な機能のすべてがカバーされています。
JCA設計の主要な原則となっているのは、暗号の概念とアルゴリズムの実装を切り離すことにより、JCAフレームワーク内で、異なるベンダーがそれぞれのツールを提供できるようにすることです。
JCAでは、それぞれが暗号化機能を提供する一連のエンジン・クラスが定義されています。たとえば、MD (メッセージ・ダイジェスト) アルゴリズムの複数の異なる標準規格があります。実装の点でそれらの標準規格はすべて異なっていますが、エンジンAPIのレベルではすべて同じです。異なるベンダーが、それぞれ特定のアルゴリズムの実装を提供することが可能です。
Java Cryptographic Extension (JCE)
暗号アルゴリズムの独立した (サード・パーティー) ベンダー実装は、Java Cryptographic Extension (JCE) と呼ばれます。Sun Microsystemsも、JCEの実装を提供しています。JCEを使用する場合には、それをJCAによって構成する必要があります。そのためには、次のことをする必要があります。
1.CLASSPATH 環境変数の中に、プロバイダーを構成するためのjarファイルのアドレスを追加する (JCE実装はすべてプロバイダーと呼ばれます)。
2. java.securityファイルを編集することによって、承認済みプロバイダーのリストの中でプロバイダーを構成する。このファイルは、JavaHome/jre/lib/securityフォルダーにあります。優先順位指定のための構文は、security.provider.<n>=<masterClassName> というものです。ここで、nは優先順位番号 (1、2、3、など) です。MasterClassName は、特定のアルゴリズム実装のためにエンジン・クラスが呼び出すマスター・クラスの名前です。マスター・クラスの名前は、プロバイダーのドキュメンテーションで指定されます。たとえば、java.securityファイルの中の次の項目について考慮してみましょう。
-
security.provider.1=sun.security.provider.Sun -
security.provider.2=com.sun.rsajca.Provider -
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
これらの項目は、エンジン・クラスがアルゴリズム実装を上記の順序で検索する、ということを示しています。最初に見つかった実装が実行されます。これらの簡単なステップを実行したなら、XML暗号化アプリケーションの中でJCA/JCEを使用することになります。
JCA/JCEに関連したすべての処理を実行する場所は、ラッパー・クラスXmlEncryption (リスト11) のGetEncryptedData() 関数です。今のところ、このメソッドは "This is Cipher Data" というストリングを戻すだけです。JCA/JCE関連のクラスは、まだ作成していません。このメソッドは、暗号化前のデータを引き数とし、それを暗号化したストリングを戻します。JCA/JCEのラッパー・クラスの作成後、アルゴリズムや鍵に関連したことは、すべてこのメソッドの中で処理することになります。
次回: このシリーズの第2回では、暗号化の詳細を検討し、それを実装します。暗号化および暗号化解除のクラスの動作や解析ロジックとの対話について示し、さらに、Web ServicesにおけるXML暗号化の応用について紹介します。
-
XML Encryption Requirements (XML暗号化の要件) およびXML Encryption Syntax and Processing (XML暗号化の構文と処理) に関する公式の情報については、それぞれのW3Cサイトをご覧ください。
-
OASIS/Robin CoverのXML Cover Pages で、XML暗号化に関する最新情報をチェックしてください。
- alphaWorksで、IBMのXML暗号化用ツールキットをダウンロードできます。
-
SUNのXML暗号化COMMUNITY PROCESS もご覧ください。
- この記事で、XPathについて述べました。それについては、O'ReillyのXML関連書籍XML in a Nutshell の中のChapter 9 XPath をご覧ください。
- この記事で、IANAについて述べました。よく使用されるデータ形式に対応する型定義については、IANAのWebサイトをご覧ください。
-
IBM Security Services にある情報は、どんなリスクが考えられるかを判別し、それに対処するためのセキュリティー・プログラムを設計する際に役立ちます。
- IBMWebSphere Studio Application Developer は、DTDやスキーマからのXML文書生成を含むJ2EE (TM) アプリケーションのビルド、テスト、および配布のための、使い勝手のよい統合開発環境です。
Bilal SiddiquiはXMLのコンサルタントです。パキスタン、ラホールのUniversity of Engineering and Technologyで電子工学を学んだのち、1995年に産業制御システム向けのソフトウェア・ソリューションの設計を始めました。その後XMLに転向し、C++ のプログラミング経験を生かしてWebおよびWAPベースのXML処理ツール、サーバー・サイド構文解析ソリューション、およびサービス・アプリケーションの構築を行うようになりました。この記事に含まれているコード・ファイルの作業用コピーをご希望の方は、wap_monster@yahoo.com のBilalまで電子メールで連絡してください。