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;
		}

もう少し調べてみたところ以下のエントリを発見。

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://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も同様。とりあえず期限切れだけでも設定した方がいい気がするけど、なんか理由があるのかな……。