JSON Web Token (JWT)

Author: Nov Matake
Date:

@novです。

個人的に最近OAuth 2.0よりJWT (というかJWS) を利用するシーンが多く、毎回同じ説明するのもめんどくさいのでブログにまとめるかと思い、どうせならOAuth.jpに書くかということで、こんな記事を書いております。

(そろそろJWTとJWSは、OpenID Foundation Japanの翻訳WGで翻訳するべき?)

JSON Web Token (JWT) とは、JSONをトークン化する仕組み。

元々はJSONデータにSignatureをつけたりEncryptionする仕組みとして考えられたものの、Signature部分がJSON Web Signatue (JWS)、Encryption部分がJSON Web Encryption (JWE) という仕様に分割された。

それぞれ2012年10月26日現在の最新仕様はこちら。

(JWTとJWSは既にだいぶ仕様が固まってきているものの、まだIETFのInternet-Draftなので注意)

JWEはまだ実際に使うケースが無いので、ここでは説明しない。

追記:
draft versionが違いますが、JWT仕様翻訳版JWS仕様翻訳版もご参考に。

Signed JWT

JWS使ってSignatureつけられたJWT。

HeaderとPayloadとSignatureという3つのセグメントから構成される。

Headerは署名アルゴリズムなどを含むJSONを、URL-safe Base64 Encodingした文字列。

Payloadは実際に送信したいJSONデータそのものを、URL-safe Base64 Encodingした文字列。

Signatureは、HeaderとPayloadを “.” で連結した文字列に対して、Headerに指定されたアルゴリズムで署名をして、その署名をURL-safe Base64 Encodingした文字列。

サンプルはJWT Spec Section 3.1 (draft 04の場合) を読むこと。

追記:
draft versionが違いますが、JWT仕様の翻訳版の該当箇所はこちら

Signature Algorithms

サポートされているアルゴリズムは、これまた別仕様のJSON Web Algorithm (JWA) で規定されている。

JWA Section 3 (draft 06 現在) では、JWSの署名アルゴリズムとして以下のアルゴリズムがサポートされている。

  • HMAC-SHA256
  • HMAC-SHA384
  • HMAC-SHA512
  • RSA-SHA256
  • RSA-SHA384
  • RSA-SHA512
  • ECDSA-SHA256
  • ECDSA-SHA384
  • ECDSA-SHA512

正直ECDSA (楕円曲線暗号) ってのは僕もよく理解していなし、Ruby以外で使いたい場合にどう書けばいいかとかさっぱりなので、個人的には共通鍵使う場合はHMAC、公開鍵使う場合はRSAを使っている。

例えば、こんな感じ。

  1. 認証サーバーからiOSアプリに渡すデータには (認証サーバーの秘密鍵を使って) RSA-SHA256使って署名
  2. iOSアプリからリソースサーバー (認証サーバーとは別) に渡すJSONには、Step 1で認証サーバーに署名されたJWSに入ってる共通鍵を利用してHMAC-SHA256使って署名
  3. リソースサーバーはiOSアプリからStep 1で発行されたJWSとStep 2で発行されたJWSを同時に受け取って、Step 1のJWSを検証した後そこに含まれてる共通鍵でStep 2のJWSを検証
  4. リソースサーバーはレスポンスに (リソースサーバーの秘密鍵を使って) RSA-SHA256使って署名

(iOSではSHA256よりSHA1の方が使いやすいらしく、HMAC-SHA1とRSA-SHA1使ってたりすることもあるが..)

各言語のライブラリ (情報求む!)

Rubyのjson-jwtとPHPのJOSE (2番目の方) は僕が作ってるので、README (希望としてはSpecも) とか読んでも使い方分からない場合は僕に直接聞いていただければと思います。

それ以外はあんまり詳しく使い方知らないので、使い方についてはドキュメント (あれば) 読むなりそれぞれの作者に直接聞いてください。それぞれの作者に紹介するくらいならできます。

node.jsとかObjective-CにもJSON Web Tokenのライブラリは見かけるのですが、HMACしかサポートしてなかったりしていまいち使えそうなの見つけられてません。(多分Google Wallet APIでHMACなJWSが使われてるので、それだけサポートしたライブラリがあるんだと予想)

ここにない言語でRSAもサポートしてるライブラリご存知でしたらお教えいただけるとうれしいです。