-
Notifications
You must be signed in to change notification settings - Fork 0
MS_XMLSignatureEncryption
- 戻る(暗号化アルゴリズム)
- XML署名・暗号
- .NETの署名・暗号化アルゴリズム
- JWS / JWE
XML 文書に対する電子署名・暗号化の仕様。
SAML や WS-Federation(WS-Federation)など、
XML ベースのフェデレーション仕様の土台になっている。
補足(位置づけ): 現在、新規に「トークンを署名する」用途では
JWS / JWE(JOSE)が選ばれる。
XML 署名が現役なのは、次のように既に XML である場面に限られる。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-c14n11xml: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 署名 | 署名が親 | 署名要素が署名対象要素の親要素となる署名形式(署名の中に対象文書が格納される) |
-
前処理
- 署名対象に対して、正規化変換を適用
- 署名対象のダイジェスト値を計算
- 参照要素(
Referenceelement)の生成- 署名対象の ID を URI 属性として追加(オプション)
- XML 正規化変換プロセス要素を追加(オプション)
- ダイジェスト値を計算し、
DigestMethod要素とDigestValue要素を追加
-
署名要素(
Signatureelement)を生成して署名対象に追加- 署名情報要素(
SignedInfoelement)を生成して署名要素に追加。- 正規化アルゴリズム要素(
CanonicalizationMethodelement) - 署名アルゴリズム要素(
SignatureMethodelement) - (前処理の)参照要素(
Referenceelement)と、その子要素。
- 正規化アルゴリズム要素(
- 署名情報要素(
-
署名を行い、署名値要素(
SignatureValueelement)を生成して
署名要素(Signatureelement)に追加。 -
署名に使用した鍵情報要素(
KeyInfoelement)を生成して
署名要素(Signatureelement)に追加(オプション)
補足: 署名の対象は「文書全体」ではなく
SignedInfo要素であることに注意。
SignedInfoの中のReferenceが
「どこを、どう正規化して、どのハッシュで測ったか」を持ち、
実際の署名値はそのSignedInfoを正規化したものに対して計算される。
この二段構えが、後述の XSW 攻撃が成立する土台になっている。
-
署名対象の検証
- 署名対象識別子 URI を参照しオリジナル署名対象を取得する。
- 署名対象から、参照要素(
Referenceelement)を抽出・削除する。 - 上記から、ダイジェスト値を計算・比較し一致を確認する。
-
署名を検証する。
- 公開鍵を取得(外部リソースか、鍵情報要素(
KeyInfoelement)から取得) -
SignedInfoを正規化してダイジェスト値を計算・比較し一致を確認する。
- 公開鍵を取得(外部リソースか、鍵情報要素(
移行メモ(正誤): 元ページは「公開鍵を取得(回部リソースか…)」
となっていたので「外部リソース」に正した。
補足(最新化・重要): XML 署名で最も知られた攻撃が
**XML Signature Wrapping(XSW)**である。
SAML 実装の脆弱性の大半はこれに由来する
(2018 年の CVE-2018-0489 など、多数の製品が影響を受けた)。仕組み
- 攻撃者は、正規の署名済みアサーションを入手する。
- それを文書内の別の場所(署名対象外の位置)に移動し、
- 偽のアサーションを、アプリが実際に読む位置に置く。
署名検証は「移動した本物」を見て通過するのに、
業務ロジックは「偽物」を読む。
「署名を検証した対象」と「値を取り出した対象」が食い違うことが本質。対策
- 署名検証済みのノードから値を取り出す(文書を XPath で再検索しない)
- スキーマ検証を厳格に行い、
ID属性の重複を拒否する- 参照 URI に外部参照・空 URI(文書全体)を許さない
- 自前実装を避け、実績のあるライブラリの検証済み API を使う
加えて、XML 特有の以下も塞ぐこと。
脅威 対策 XXE(外部実体参照) DTD を無効化(.NET は XmlReaderSettings.DtdProcessing = Prohibit)XSLT 変換の悪用 Transformsに許可するアルゴリズムを限定署名アルゴリズムのダウングレード SHA-1( rsa-sha1)を拒否し、rsa-sha256以上を要求KeyInfoの鍵を鵜呑み信頼済みの鍵とだけ照合する(文書内の鍵で検証しない)
-
SAMLを実装する。を参照。
-
.NET では
System.Security.Cryptography.Xml名前空間
(SignedXmlクラス)を使用する
(.NETの署名・暗号化アルゴリズムを参照)。
仕様に暗号化に関する項目はあるが、具体的でなく実装もなさそう。
補足: 元ページの記述時点では「実装もなさそう」とされているが、
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 モードを受け付けないこと。
-
XMLデジタル署名とXML暗号:Webサービスのセキュリティ(2)
https://www.atmarkit.co.jp/ait/articles/0207/24/news001.html -
RFC 3275 - (Extensible Markup Language) XML-Signature Syntax and Processing
https://datatracker.ietf.org/doc/html/rfc3275 -
XML Signature Syntax and Processing Version 1.1(W3C Recommendation)
https://www.w3.org/TR/xmldsig-core1/ -
XML Encryption Syntax and Processing Version 1.1(W3C Recommendation)
https://www.w3.org/TR/xmlenc-core1/
Tags: 移行, .NET開発, セキュリティ, 暗号化, 証明書
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。