しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

Twitter API と OAuth の実装 (2)

さて、OAuth で一番わかり難い署名の生成についてまとめます。ここでは HMAC-SHA1 だけ扱うことにします。

キーの生成

HMAC で使うキーを作る必要があります。当然ですね。キーはパラメータエンコードされたコンシューマシークレットとトークンシークレットを "&" で繋げるだけです。

注意点としては、トークンシークレットは存在しない場合があることです。落ち着いてトークンシークレットを空文字列として扱ってあげましょう。

var HMAC_KEY = UrlEncode("CONSUMER_SECRET") + "&" + UrlEncode("TOKEN_SECRET");

まあ、結局はこれだけです。そして作ったキーはバイト列にして HMACSHA1 クラスの Key プロパティに指定してあげます。

var hmac = new HMACSHA1();
hmac.Key = Encoding.ASCII.GetBytes(HMAC_KEY);

これでキーの準備は完了です。次は HMACSHA1 クラスに食わせる文字列を作ります。

署名を作成する元を用意

材料は oauth_ から始まる oauth_signature 以外のパラメータと追加のパラメータです。追加のパラメータってのは GET の時は URL に付けるクエリ文字列、POST で application/x-www-form-urlencoded の時はメッセージボディのパラメータのことです。

それらを全て繋げて署名を作成します。その繋げ方は以下になります。

  1. パラメータ名でソートする
    • 同じパラメータ名が存在するときには値でさらにソート
  2. パラメータ名、値をパラメータエンコードで変換し、"&" で繋げる
  3. HTTP メソッド名(大文字)、リクエスト URL(小文字)、1 つ前で繋げたパラメータ の順番でパラメータエンコードの後 "&" で繋げる

わかり難いのが、パラメータは 2 回パラメータエンコードされるという点。最初、1 回しかエンコードしていなかったので、署名の検証が通らず困り果てていました。

var signaturebase = "HTTP METHOD" + "&" + UrlEncode("REQUEST URL") + "&" + UrlEncode("PARAMETERS");

上のようなコードを書く必要があります。実際には string.Format とか使ったほうが楽だけど、本質的な部分ではないのでパス。

後はこれを HMACSHA1 に食わせて、生成されたハッシュのバイト列を Base64 で変換してやれば完成です。