2005-05-20
■ Atom APIのWSSE認証について
WSSEのpasswordDigestの計算方法には、
- PasswordDigest = base64(sha1(Nonce . Created . パスワード)) … (type-A)
- PasswordDigest = base64(sha1(base64_decode(Nonce) . Created . パスワード)) … (type-B)
の2種類がある。上の式でNonceとCreatedはヘッダから取得した生の文字列。ここでは仮に上の方式をtype-A、下のをtype-Bと呼ぶことにする。
- http://watcher.moe-nifty.com/memo/2004/07/_livedoor_blog_.html
- http://www.witha.jp/blog/archives/000076.html
ポインタだけですが、
http://search.cpan.org/src/BTROTT/XML-Atom-0.08/Changes
いわく、0.06 2004.04.14
- BACKWARDS INCOMPATIBILITY:
Fixed Nonce behavior in API. Nonce should be sent in base64-encoded form in SOAP and REST requests, but decoded (raw) nonce should be used when generating PasswordDigest.
この決定がなされた根拠は、たぶん以下のあたり。
なお、nonce 値は復号化された値のオクテット列を使用してハッシュされますが、タイムスタンプは要素のコンテンツで指定したとおりに UTF8 で符号化したオクテット列を使用してハッシュされます。
/wsse:Nonce/@EncodingType
この属性は省略可能で、nonce 値の符号化の種類を指定します (BinarySecurityToken の有効値に関する WS-Security の定義を参照してください)。この値を指定しない場合、デフォルトの Base64 符号化が使用されます。
なんだかtype-Bが正しそうな感じ。以下、Atom APIのX-WSSEヘッダのサンプルを収集。
http://www.sixapart.com/pronet/docs/typepad_atom_api
ID:Melody/Pass:Nelson (type-A) X-WSSE: UsernameToken Username="Melody", PasswordDigest="VfJavTaTy3BhKkeY/WVu9L6cdVA=", Created="2004-01-20T01:09:39Z", Nonce="7c19aeed85b93d35ba42e357f10ca19bf314d622"
http://www.xml.com/pub/a/2003/12/17/dive.html
ID:bob/Pass:taadtaadpstcsm (type-A) X-WSSE: UsernameToken Username="bob", PasswordDigest="quR/EWLAV4xLf9Zqyw4pDmfV9OY=", Nonce="d36e316282959a9ed4c89851497a717f", Created="2003-12-15T14:43:07Z"
type-Aの2個しかみつからなかった。。のでBlogWriteを使って生成。
ID:test/Pass:abc (type-B) X-WSSE: UsernameToken Username="test", PasswordDigest="6nT2UoeeEkM3mkFImvavlEtuock=", Nonce="MGJxamJ6YTAzcmZj", Created="2005-05-20T10:25:41Z" ID:alice/PASS:bob (type-B) X-WSSE: UsernameToken Username="alice", PasswordDigest="PWzDvhfsBksWqFIf7Z10xWDfkXc=", Nonce="ZDBnZ3ZtdGdqNWRr", Created="2005-05-21T16:36:29Z" ID:alice/PASS:bob (type-B) X-WSSE: UsernameToken Username="alice", PasswordDigest="9W1jK0Ab9JGsDo+xhk2DBq1c9TY=", Nonce="dzdya3V0c2M0ajdw", Created="2005-05-21T16:38:17Z" ID:bob/PASS:alice (type-B) X-WSSE: UsernameToken Username="bob", PasswordDigest="dpHVLxP1cQL1hCILT95tDYGfFQ8=", Nonce="emxjbXR5YzZ5NjVl", Created="2005-05-21T16:37:15Z" ID:bob/PASS:alice (type-B) X-WSSE: UsernameToken Username="bob", PasswordDigest="ihYOU3B76tj3q1zZBqkVgN/YZEI=", Nonce="c21uZnIzczdzbHY2", Created="2005-05-21T16:38:45Z"
Sixapartのサンプルはtype-Aになっているけれど、MTの最新版をみたら(3.16)type-Bになってた。
$auth->{Nonce} = MIME::Base64::decode_base64($auth->{Nonce});
my $expected = Digest::SHA1::sha1_base64(
$auth->{Nonce} . $auth->{Created} . $user->password);
BlogWriteが送っているリクエストを見るために、httpdump.plを使った。
(追記) type-Aのサービスはもう残っていないのかと思っていましたが、
- http://watcher.moe-nifty.com/memo/2005/06/_atom_api___typ_c96f.html
- http://d.hatena.ne.jp/tsupo/20050620/1119230006
MovableType は 3.17 (3.16から?) で type-B になったことが確認されているので、TypePad も 1.5 で追随したのかと思いきや、追随してないことがわかりました。
いえ、TypePad では両方をサポートしているはずです。
当初の仕様書が曖昧であったために、type-A を送信してくるクライアントも存在するため、両方の方式をサポートしています。
IETF に移ったAtom PP では、WSSE認証を使用せず HTTPS + Basic 認証となるので、この問題は後方互換の対応ということになります。
投稿者: miyagawa (2005.06.20 午前 11:58)
Basic認証になるのかー……。
(さらに追記) http://bitworking.org/projects/atom/draft-ietf-atompub-protocol-04.html
The security of Atom is based on HTTP Digest Authentication and/or [@@TBD@@ CGI Authentication]. Any weaknesses in either of these authentication schemes will obviously affect the security of the Atom Publishing Protocol.
むむ?Digest認証かCGI認証って書いてある。CGI認証の1つがWSSE認証?
What about authentication?
The Atom spec requires that a server support either HTTP digest authentication, which can be difficult for some bloggers to implement (depending on their ISP and web server), or CGI authentication, which can be a lot easier to implement (I believe WSSE qualifies as CGI authentication, and that's what my Atom implementation uses).
■ WSSEでのnonceのキャッシュ
タイムスタンプと nonce 値は、リプレイを検出するために最短でも 5 分間はキャッシュすること、および 5 分以上経過したタイムスタンプは拒否することが推奨されます (RECOMMENDED)。
はてなフォトライフはキャッシュしてない感じ。時間制限もしてないっぽい。Livedoor Blogも同様。とりあえず期限切れだけでも設定した方がいい気がするけど、なんか理由があるのかな……。
ちなみにBlogWriteの現バージョン(1.4.1.0)は常にBasic認証を同時に送信しているように見える。これだとWSSEのメリットが損なわれてしまうんじゃないだろうか。(追記) 2のベータでは選択できるようになってました。
WSSEがなぜこういうデザインになっているかについては、以下の文章がわかりやすかった。