こんにちは!ネットワークの迷宮を日々彷徨う、セキュリティ・ライターの「兄貴」です。
今日は、SAML認証の裏側で密かに火花を散らしている「XML署名」と、そのややこしい難敵「正準化(Canonicalization)」についてお話しします。
「SAML? XML? 署名?」と身構える必要はありません。これらはすべて、「届けられた手紙が、途中で誰にも書き換えられていないこと」を証明するための仕組みです。郵便配達に例えて、一歩ずつ紐解いていきましょう!
—
1. SAML署名:手紙の封印と「割り印」の秘密
SAML認証において、IDプロバイダー(IdP)からサービスプロバイダー(SP)へ送られる認証レスポンスは、いわば「身分証明書が入った封筒」です。
もし途中で悪意ある第三者がこの封筒を開けて、「権限:一般ユーザー」を「権限:管理者」に書き換えたらどうなるでしょう? 大惨事ですよね。これを防ぐのが ds:Signature という要素です。
これは、手紙の封筒の合わせ目に押す「割り印」のようなもの。封筒の中身を計算して特殊な値(ハッシュ)を作り、それを送信者の秘密鍵で暗号化して「署名」として添えるのです。受信者は、受け取った手紙を同じ手順で計算し、署名と突き合わせることで、「一文字も改ざんされていない」ことを確認できます。
—
2. なぜ「正準化(Canonicalization)」が必要なのか?
ここで一つ、厄介な問題が発生します。コンピュータの世界では、同じ意味のデータでも、書き方が微妙に違うことがよくあるんです。
例えば、HTMLやXMLでは、半角スペースの数や、改行コードの有無、属性の順番が違っていても、ブラウザやアプリは「同じもの」として扱います。
- 書き方A:
<User name="Tarou" id="123"> - 書き方B:
<User id="123" name="Tarou" >
人間が見れば同じですが、コンピュータが「ハッシュ(指紋のようなもの)」を計算すると、これらは全くの別物になってしまいます。これでは、署名が正しく検証できませんよね。
そこで登場するのが 「正準化(Canonicalization)」 です。
これは、「どんな書き方をしていても、一定のルールに従って、誰がやっても同じ形式に整える」 という作業のこと。いわば、手紙を出す前に「すべての手紙は、決まったフォーマットの便箋に、指定された順序で書くこと!」とルールを決めて、それを強制的に適用するようなものです。
特にSAMLでよく使われる Exclusive Canonicalization(排他的正準化)は、周囲の余計な情報に左右されず、その要素そのものだけを確実に検証できるように整える、非常に賢い方式なんですよ。
—
3. 実践!XML署名の構造を覗いてみる
実際にSAMLレスポンスの中を覗くと、こんな構造になっています。
<!-- 署名対象のデータ(Assertion) -->
<saml:Assertion ID="_12345">
<saml:Subject>...</saml:Subject>
<!-- ここからが署名情報 -->
<ds:Signature>
<ds:SignedInfo>
<!-- 排他的正準化アルゴリズムを指定 -->
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<!-- 署名アルゴリズム -->
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_12345">
<!-- 署名前にこのルールで整えることを宣言 -->
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>ここに計算されたハッシュ値が入る</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>ここに秘密鍵で暗号化した署名値が入る</ds:SignatureValue>
</ds:Signature>
</saml:Assertion>
このコードの中にある http://www.w3.org/2001/10/xml-exc-c14n# というのが、「排他的正準化」の呪文です。これがあることで、システム同士で「このルールで整えてから検証しようね!」と約束できているわけです。
—
4. 現場でのトラブルシューティング:なぜ署名エラーが起きるのか?
現場で「署名検証エラー」が出たとき、原因の9割はこれです。
1. 改行コードの罠: Windowsの改行(CRLF)とLinuxの改行(LF)が混ざってしまい、正準化後のデータが微妙にズレてしまう。
2. 証明書の不一致: IdPが署名に使った公開鍵と、SP側で設定している公開鍵が古い(または間違っている)。
3. 時刻のズレ: SAMLには NotOnOrAfter などの期限がありますが、サーバーの時計がずれていると、署名以前の問題で拒否されることがあります。
もしエラーに遭遇したら、まずは 「送られてきたXMLをそのまま保存し、正準化ルールに従って再計算して、署名値と一致するか」 をログレベルを上げて確認してみてください。
—
最後に:完璧を求めすぎないことも大切
ゼロトラストの世界では、「すべてを疑う」ことが基本です。しかし、XML署名は複雑であるがゆえに、実装の些細な揺れでエラーが起きやすいのも事実。
だからこそ、私たちは「どの部分を署名対象にするか」「どの正準化アルゴリズムを使うか」を厳密に定義し、ドキュメントに残しておく必要があります。
最初は難しく感じるかもしれませんが、「手紙の封印を解くための共通ルールを決めているだけ」と考えれば、少しだけ身近に感じませんか?
ネットワークのセキュリティは、こうした小さな「整合性」の積み重ねでできています。皆さんの現場の平和を、今日も祈っていますよ!それでは、また次の記事でお会いしましょう。
コメント