XML署名とは
XML署名(XML Signature)は、XML文書に対するデジタル署名のための
W3C勧告です。XMLDSig、XML-DSig、XML-Sigとも呼ばれます。PKCS#7と共通の機能が多いですが、XML文書の署名に特化した拡張が施されています。
XML署名の目的
XML署名は、XML文書を含む任意のリソースに対してデジタル署名を行うために利用されます。署名方法には、以下の3種類があります。
detached署名: 署名対象のリソースが、署名を含むXML文書の外にある場合に使用します。
enveloped署名: 署名対象のリソースが、署名を含むXML文書の一部分である場合に使用します。
enveloping署名: 署名対象のリソースが、署名自身の中に含まれている場合に使用します。
XML署名の構造
XML署名は、`http://www.w3.org/2000/09/xmldsig#`の名前空間で定義される`Signature`要素を基本構造としています。以下に、その構造を示します。
xml
...
SignedInfo要素: 署名対象の情報や使用するアルゴリズムを指定します。`SignatureMethod`と`CanonicalizationMethod`要素は、`SignatureValue`要素で利用され、改ざんを防ぐために`SignedInfo`に含まれます。
Reference要素: 署名対象のリソースをURIで指定します。`Transforms`要素でハッシュ計算前に適用する変換を、`DigestMethod`要素でダイジェストアルゴリズムを、`DigestValue`要素でハッシュ値をBase64エンコードした値を指定します。
SignatureValue要素: `SignedInfo`要素を正規化し、署名アルゴリズムで生成された署名値をBase64エンコードした値を格納します。
KeyInfo要素: 署名の検証に必要な鍵情報を格納します。通常はX.509証明書が含まれます。この要素がない場合は、受信者がデータから鍵を特定する必要があります。
Object要素: enveloping署名の場合に、署名対象のデータを含めるために使用します。
検証プロセスとセキュリティ
XML署名の検証は、以下の手順で行われます。
1.
リファレンス検証: 各`Reference`要素のダイジェスト値は、指定されたリソースを取得し、変換を適用後、ダイジェストアルゴリズムで計算されます。計算結果は`DigestValue`と照合され、不一致の場合は検証失敗となります。
2.
署名検証: `SignedInfo`要素を正規化し、`KeyInfo`要素から取得した鍵を使って署名を検証します。検証プロセスは、リソースが署名されたものであることを証明しますが、正規化と変換の拡張性により、署名された内容の正確性を検証する必要もあります。
XML正規化
XML文書は、空白などの違いにより、複数の表現方法が存在し得ます。デジタル署名はシリアル化されたデータに基づいて生成されるため、わずかな違いでも署名値が大きく変化します。XML署名では、論理的に同一のXML文書が同じ署名値を生成するように、正規化を行います。
デフォルトの正規化アルゴリズムでは、名前空間の扱い方に問題があり、他のドキュメントを組み込むと期待通りの結果になりません。そのため、周囲のXMLに依存しない排他的正規化も開発されています。
批評
XML正規化は、その複雑さ、処理要件、パフォーマンスの低さから批判されています。特に、トランザクションやSOAアプリケーションでは、待ち時間が増加し、解決が難しいという問題点があります。
関連情報
Canonical XML: XMLの正規化に関する仕様
XML暗号化: XMLデータの暗号化に関する仕様
XAdES: ヨーロッパにおける電子署名に関する標準仕様
外部リンク
Performance of Web Services Security
W3C workshop presentation on XML security
Performance Comparison of Security Mechanisms for Grid Services
Why XML canonicalization is bad for Web Services Security
XML-Signature Syntax and Processing (W3C)
Canonical XML
Exclusive XML Canonicalization
Why XML Security is Broken
XMLSignatures Java binding for XMLBeans and JAXB.