Skip to content

MS_XMLSignatureEncryption

nishi_74322014 edited this page Aug 13, 2026 · 1 revision

XML署名・暗号

概要

XML 文書に対する電子署名・暗号化の仕様。
SAML や WS-Federation(WS-Federation)など、
XML ベースのフェデレーション仕様の土台になっている。

補足(位置づけ): 現在、新規に「トークンを署名する」用途では
JWS / JWE(JOSE)が選ばれる。
XML 署名が現役なのは、次のように既に XML である場面に限られる。

  • SAML のアサーション・メタデータ
  • XAdES(長期署名)、電子入札・電子申請系の文書
  • SOAP(SOAP)の WS-Security

XML 署名は「文書の一部だけに署名できる」という強力さを持つが、
その柔軟さがそのまま後述の攻撃面になっている。

署名

XML Digital Signature 標準の RFC 3275。

移行メモ(正誤): 元ページは「RFC3075」としていたが、
RFC 3075 は 2001 年の初版で、
RFC 3275(2002 年、Draft Standard)によって置き換えられている
W3C 側の最新勧告は XML Signature Syntax and Processing Version 1.1(2013 年)。

特徴

書目に関する情報

XML の文法で統一して表現できる。

  • 署名対象
  • 署名アルゴリズム
  • 署名値
  • 証明書

署名付加方法

XML に追加するので、ASN.1 構文に比べて分かりやすい。

署名範囲

XML 文書の一部に対しても署名を付けることができる。

アルゴリズム等の識別子

W3C などで定めている URI を使用する。

構文

  • XML 文書の正規化(Canonicalization:C14N)を行う。

移行メモ(正誤): 元ページは「RFC3076 の Canonicalization:C14N」
としていたが、RFC 3076 は Canonical XML 1.0(2001 年)である。
現在は用途に応じて次を使い分ける。

方式 URI の末尾 用途
Canonical XML 1.0 xml-c14n20010315 基本形
Exclusive C14N 1.0 xml-exc-c14n# SAML など、署名済み要素を別文書へ移す場合(祖先の名前空間を引きずらない)
Canonical XML 1.1 xml-c14n11 xml:base の扱いを改善

フェデレーション用途ではExclusive C14N が事実上の標準である。
通常の C14N を使うと、アサーションを別のメッセージに埋め込んだ際に
祖先要素の名前空間宣言が取り込まれ、署名が壊れる。

  • 署名要素に対して

    • 正規化方法
    • ダイジェスト値と署名値の計算方法と計算値
    • XML 署名に使用した鍵情報(KeyInfo)要素(オプション)

    を挿入する。

  • Signature 要素は、下記のように記述される。

<Signature ID?>                 <!-- XML署名要素 -->
  <SignedInfo>                  <!-- 署名情報要素 -->
    <CanonicalizationMethod/>   <!-- 署名対象正規化アルゴリズム要素 -->
    <SignatureMethod/>          <!-- 署名アルゴリズム要素 -->
    (<Reference (URI=)? >       <!-- 参照要素(URIは署名対象の識別子) -->
      (<Transforms/>)?          <!-- 正規化変換プロセス要素 -->
      <DigestMethod/>           <!-- ダイジェスト計算アルゴリズム要素 -->
      <DigestValue/>            <!-- 署名対象のダイジェスト値要素 -->
    </Reference>)+              <!-- 1つ以上の参照要素 -->
  </SignedInfo>
  <SignatureValue/>             <!-- 署名値要素 -->
  (<KeyInfo>                    <!-- 鍵情報要素:オプション -->
     <KeyValue/>                <!-- 検証鍵要素 -->
     <X509Data/>                <!-- X.509証明書要素 -->
   </KeyInfo>)?
  (<Object ID?>)*               <!-- XML署名対象要素:オプション -->
</Signature>

移行メモ: 元ページの要素名は <X.509Data/> だったが、
スキーマ上の要素名は <X509Data/>(ピリオドなし)である。

種別

Envelope は、封筒の意味。

種別 関係 内容
Detached 署名 独立 署名対象要素と署名要素が独立した署名形式(署名対象が別のファイルである場合や、同じ XML 文書内でも要素の親子関係がないときなど)
Enveloped 署名 署名が 署名要素が署名対象要素の子要素となる署名形式(対象文書の中に署名が格納される)
Enveloping 署名 署名が 署名要素が署名対象要素の親要素となる署名形式(署名の中に対象文書が格納される)

署名・検証

署名

  • 前処理

    • 署名対象に対して、正規化変換を適用
    • 署名対象のダイジェスト値を計算
    • 参照要素(Reference element)の生成
      • 署名対象の ID を URI 属性として追加(オプション)
      • XML 正規化変換プロセス要素を追加(オプション)
      • ダイジェスト値を計算し、DigestMethod 要素と DigestValue 要素を追加
  • 署名要素(Signature element)を生成して署名対象に追加

    • 署名情報要素(SignedInfo element)を生成して署名要素に追加。
      • 正規化アルゴリズム要素(CanonicalizationMethod element)
      • 署名アルゴリズム要素(SignatureMethod element)
      • (前処理の)参照要素(Reference element)と、その子要素。
  • 署名を行い、署名値要素(SignatureValue element)を生成して
    署名要素(Signature element)に追加。

  • 署名に使用した鍵情報要素(KeyInfo element)を生成して
    署名要素(Signature element)に追加(オプション)

補足: 署名の対象は「文書全体」ではなく
SignedInfo 要素であることに注意。
SignedInfo の中の Reference
「どこを、どう正規化して、どのハッシュで測ったか」を持ち、
実際の署名値はその SignedInfo を正規化したものに対して計算される。
この二段構えが、後述の XSW 攻撃が成立する土台になっている。

検証

  • 署名対象の検証

    • 署名対象識別子 URI を参照しオリジナル署名対象を取得する。
    • 署名対象から、参照要素(Reference element)を抽出・削除する。
    • 上記から、ダイジェスト値を計算・比較し一致を確認する。
  • 署名を検証する。

    • 公開鍵を取得(外部リソースか、鍵情報要素(KeyInfo element)から取得)
    • SignedInfo を正規化してダイジェスト値を計算・比較し一致を確認する。

移行メモ(正誤): 元ページは「公開鍵を取得(回部リソースか…)」
となっていたので「外部リソース」に正した。

攻撃と対策

補足(最新化・重要): XML 署名で最も知られた攻撃が
**XML Signature Wrapping(XSW)**である。
SAML 実装の脆弱性の大半はこれに由来する
(2018 年の CVE-2018-0489 など、多数の製品が影響を受けた)。

仕組み

  1. 攻撃者は、正規の署名済みアサーションを入手する。
  2. それを文書内の別の場所(署名対象外の位置)に移動し、
  3. 偽のアサーションを、アプリが実際に読む位置に置く

署名検証は「移動した本物」を見て通過するのに、
業務ロジックは「偽物」を読む。
「署名を検証した対象」と「値を取り出した対象」が食い違うことが本質。

対策

  • 署名検証済みのノードから値を取り出す(文書を XPath で再検索しない)
  • スキーマ検証を厳格に行い、ID 属性の重複を拒否する
  • 参照 URI に外部参照・空 URI(文書全体)を許さない
  • 自前実装を避け、実績のあるライブラリの検証済み API を使う

加えて、XML 特有の以下も塞ぐこと。

脅威 対策
XXE(外部実体参照) DTD を無効化(.NET は XmlReaderSettings.DtdProcessing = Prohibit
XSLT 変換の悪用 Transforms に許可するアルゴリズムを限定
署名アルゴリズムのダウングレード SHA-1(rsa-sha1)を拒否し、rsa-sha256 以上を要求
KeyInfo の鍵を鵜呑み 信頼済みの鍵とだけ照合する(文書内の鍵で検証しない)

ライブラリ

暗号化

仕様に暗号化に関する項目はあるが、具体的でなく実装もなさそう。

補足: 元ページの記述時点では「実装もなさそう」とされているが、
XML Encryption Syntax and Processing(W3C 勧告、2002 年 / 1.1 は 2013 年)
という独立した仕様が存在し、実装もある。

  • .NET では EncryptedXml クラスが対応する
    *.config の構成セクション暗号化にも使われている)。
  • SAML では <EncryptedAssertion> /
    <EncryptedID>(暗号化された NameID)として使われる。

構造は JWE と同じハイブリッド暗号である。

XML Encryption JWE の対応物
<EncryptedKey>(受信者の公開鍵でセッション鍵を暗号化) JWE Encrypted Key(alg
<EncryptedData>(セッション鍵で本文を暗号化) JWE Ciphertext(enc

注意: XML Encryption の CBC モードには
**パディング オラクル攻撃(Jager & Somorovsky, 2011)**が知られており、
1.1 で対策(AES-GCM の採用)が入っている。
新規実装では GCM を使い、CBC モードを受け付けないこと。

参考


Tags: 移行, .NET開発, セキュリティ, 暗号化, 証明書

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally