as3corelibのWSSEUsernameTokenについて
Fotolife Boothでは、はてなフォトライフAtomAPIを利用しています。で、WSSE認証にas3corelibの com.adobe.crypto.WSSEUsernameToken を使っているのですが、これそのままだと認証が通りません。CPANモジュールのXML::Atom::Clientを使うと認証通るので、なんでかなーと少しはまりました。WSSEUsernameTokenとXML::Atom::Clientのソースをそれぞれ見て何が違うか調べたら、どうやらNonceの扱い方が異なるようで、XML::Atom::Clientのやり方にあわせてWSSEUsernameTokenのソースを修正したらうまくいきました。
--- com/adobe/crypto/WSSEUsernameToken.as.orig 2007-06-11 12:21:05.000000000 +0900 +++ com/adobe/crypto/WSSEUsernameToken.as 2007-06-11 12:20:49.000000000 +0900 @@ -66,7 +66,7 @@ { nonce = generateNonce(); } - nonce = base64Encode(nonce); + var nonce_enc:String = base64Encode(nonce); var created:String = generateTimestamp(timestamp); @@ -77,7 +77,7 @@ var token:String = new String("UsernameToken Username=\""); token += username + "\", " + "PasswordDigest=\"" + password64 + "\", " + - "Nonce=\"" + nonce + "\", " + + "Nonce=\"" + nonce_enc + "\", " + "Created=\"" + created + "\""; return token; }
もう少し調べてみたところ以下のエントリを発見。
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://tech.g.hatena.ne.jp/koseki/20050520
as3corelibのWSSEUsernameTokenはtype-Aで、はてなフォトライフやXML::Atom::Clientはtype-Bって事のようです。
それともうひとつ。WSSEUsernameTokenが生成するCreatedの値がUTC表記なのにローカル時間になってます。つまり9時間進んだ時刻になってるわけですが、時間制限を厳密に行う相手だと拒否されるかもしれませんね。はてなフォトライフでは制限してないようです。
上で引用したエントリの最後にも次のように書かれてます。
■ WSSEでのnonceのキャッシュ
* http://www.microsoft.com/japan/msdn/webservices/spec/ws-security-addendum.asp
タイムスタンプと nonce 値は、リプレイを検出するために最短でも 5 分間はキャッシュすること、および 5 分以上経過したタイムスタンプは拒否することが推奨されます (RECOMMENDED)。
はてなフォトライフはキャッシュしてない感じ。時間制限もしてないっぽい。Livedoor Blogも同様。とりあえず期限切れだけでも設定した方がいい気がするけど、なんか理由があるのかな……。