Open棟梁Project - マイクロソフト系技術情報 Wiki
目次 †
概要 †
JWTとはJSON Web Tokenの略でjot(ジョット)と発音する。
仕様 †
- JSONのアサーション(クレーム)を生成するための仕様
- Base64 URL Encodeしたヘッダ、クレームセット等を「.」で連結
- このため、url-safeであり、Webでの取り扱いが楽。
- 言語毎のライブラリも整っており、相互運用が容易。
用途 †
- 暗号化により、鍵でペイロード(クレームセット)の改ざんチェック可能。
- この特徴のため、仲介者を伴う(改竄・盗聴の危険性がある)情報のやり取りに利用される。
種類 †
JWTを作る方法としてJWSとJWE、もしくは両方を使った方法がある。
- JWSは、暗号化ではなく署名なので、JSON の中身は誰でも見られる。
通常、発行者だけが秘密鍵で検証できるが、公開鍵を使用すれば誰でも検証が可能。
注意 †
「Base64」ではなく「Base64 URL」なので「=」は含まれない。
構造 †
構成要素 †
以下の要素から構成される。
ヘッダ †
署名検証のために利用するもの。
ペイロード(クレームセット) †
- 予約済みクレーム
- パブリッククレーム
- プライベートクレーム
署名 †
色々な暗号化アルゴリズムを使用して作成した署名
JWTの種類 †
JWS †
署名されたJWT
- 署名付きのデータを JSON (の Base64 URL Encode) 形式で表現するための仕様
- 多くの場合は JSON Payload に対して署名するケースで利用される。
- OpenID Connect の ID Tokenなどで利用されている。
BASE64URL (UTF-8 (Header))
.
BASE64URL (UTF-8 (Claim Set))
.
BASE64URL (UTF-8 (Signature))
JWE †
暗号化されたJWT
- 暗号化されたデータを JSON (の Base64 URL Encode) 形式で表現するための仕様
- 暗号化されたSAML アサーションを Connect に移行するユースケースなどが想定される。
ヘッダー.キー.初期ベクター.暗号文.認証タグ
BASE64URL (UTF-8 (JWE Protected Header))
.
BASE64URL(JWE Encrypted Key)
.
BASE64URL(JWEInitialization Vector)
.
BASE64URL(JWE Ciphertext)
.
BASE64URL(JWE Authentication Tag)
プレーンJWT †
ヘッダ内のalgはnone = {“alg”: “none”} 。
ヘッダー.ペイロード.
BASE64URL (UTF-8 (Header))
.
BASE64URL (UTF-8 (Claim Set))
.
その他 †
- JWK
- JWS や JWE などで利用する「鍵」を JSON 形式で表現するための仕様
- OpenID Connect Discovery をサポートしている IdP は公開鍵を JWK Set 形式で公開していることが多い。
- JWA
- JWS や JWE で利用される各アルゴリズムおよびそれらの識別子を定義している仕様
- ・・・
JWTの作成と検証手順 †
- 署名・暗号化は特定用途であれば、1パターン実装すればイイので自作も可能。
- 検証・復号化は網羅性を高めることが難しいので、ライブラリを使用する。
ライブラリ †
JWTの作成手順 †
概要 †
- JWSまたはJWEの手順に従って生成
- 入れ子になったJWTの場合にはヘッダの”cty”の値に”JWT”を指定
手順(JWS) †
- ヘッダを生成し、UTF-8のバイト文字列に変換し、BASE64urlエンコード。
- クレームセットを生成し、UTF-8のバイト文字列に変換し、BASE64urlエンコード。
- BASE64urlエンコード済みのヘッダとクレームセットを
ピリオドで連結する、UTF-8バイト文字列に変換し、BASE64urlエンコード。
- 上記をヘッダで指定した暗号化プロバイダで暗号化(ハッシュ or 暗号化)
JWTの検証手順 †
手順 †
- JWTをヘッダ、クレームセット、署名に分割しBASE64urlでデコード。
- ヘッダから種類(JWT、JWS、JWE)、暗号化プロバイダを確認する。
- 種類、暗号化プロバイダを考慮してJWTの検証を行なう。
- 検証完了後、クレームセット内の有効期限の検証も行なう。
検証サイト †
ユースケース †
認証用途 †
コチラを参照。
OAuth 2.0のアクセストークン †
- Implicitグラント種別のアクセストークンで、認証用途に利用する。
アクセストークンに、OpenID ConnectのIDトークンを参考にして、改竄、置換、CSRF(XSRF)等に
耐える為のクレームを追加し、これを検証すれば、Implicitグラント種別でも安全性が高くなる。
- Google の OAuth Token は、公開鍵暗号(非対称鍵暗号)で署名されたJWT であるため、
クライアントは公開鍵を取得し、Google API に検証リクエストをしないで検証が可能。
シングルサインオン(SSO) †
- ショップ(Webアプリ)とカート(WebAPI+SPA)を分離し、
tempストアをサイト間で共有しないで、認証情報を共有するSSOを実現したい。
- JWTにより、以下を跨いだ認証が可能に。
- サーバー(Webアプリ・WebAPI)間
- クライアント(ブラウザ)・サーバー(Webアプリ・WebAPI)間
- マイクロサービス化にも対応可能になる。
サービスの多様化、フロントエンドの多極化
- 認証情報以外の共有したい情報にも利用することができる。
この場合、JWEを使用する可能性がある(HTTPSなら不要だが)。
メール着信確認トークン †
以下でメール着信確認トークンを使用するようなケースで利用する事で、
トークンをtempストアに格納して、後に比較するような実装が不要になる。
- アカウント確認(E-mail confirmation)
- パスワード・リセット
共有用URL †
- OneDrive?のファイル・フォルダ共有にも利用されている。
- URLにオブジェクトに対するACL・ACE的なモノをJWTアサーションに同梱。
- サービスが認証したユーザがオブジェクトに対するアクセス許可を持っているか、ACL・ACEから確認する。
RFC †
Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants †
https://tools.ietf.org/html/rfc7521
- OAuth 2.0 を拡張するアサーションの仕様
- Client Authentication で Client Credentials として使うアサーションの仕様
- Authorization Codeグラント種別のAccess Token と交換するアサーションの仕様
- 単体では利用できず、後の2つのサブ仕様
(RFC7522(SAMLアサーション)、7523(JWTアサーション))
の共通部分を抽象化した仕様になっている。
JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants †
https://tools.ietf.org/html/rfc7523
JWT を RFC 7521(上記) の アサーション として利用するための仕様
参考 †
.NETのJWTライブラリ †
相性がある模様 †
Microsoft Open Technologiesによって開発された、
JSON Web Token Handler For the Microsoft .Netというライブラリ。
下記が参考になる。
上記は、ResourcesOwner?であるユーザが介在することなく
ClientがResourcesServer?のAPIを利用するようなユースケースらしく、
以下の様な、grant_typeで、AccessToken?を取得して、WebAPIにアクセスする。
この時、Googleの秘密鍵のキー長は1024bitだが、
このライブラリは最低でも2048bitを要求しているため、
相互運用が不可だったらしい。
恐らく、色々なライブラリ間の実装差異で
相互運用が難しくなるようなケースがあると思う。
以下の2メソッドのインターフェイスを確認すると、
引数・戻り値に、Microsoft.Owin.Security.AuthenticationTicket?が在ったり、
.NET技術と結合度が高く、相互運用には向かないように見える。
検索結果 †
- NugetやWebを検索した所、以下の2ライブラリの利用者が多い。
- ダウンロード数を確認した所、System.IdentityModel?.Tokens.Jwtが優勢。
JSON Web Token (JWT) implementation for .NET †
Version Historyを参照。
System.IdentityModel?.Tokens.Jwt †
以前は、JSON Web Token Handler For the Microsoft .Netという表示名だったようだが、
version 05-00からは、パッケージ名(=名前空間)と同じ表示名になっている。
ライセンスはMITだが、ソースコードをGithubやCodePlex?上に確認できない・・・。
上記の、BCL入りしているJwtSecurityTokenHandler?が含まれる名前空間より
一つ下の階層のJWT系の追加ライブラリを格納する名前空間であるもよう。
必要に応じて、追加でNugetから取得する必要がある。
詳しくは、Version Historyを参照。
自作ライブラリについて †
用途 †
- 認証など、特定用途の署名・暗号化、検証・復号化レベルであればであれば自作ライブラリで良い。
- 正しく署名・暗号化できていれば、他のライブラリでも検証・復号化が可能。
相互運用(検証・復号化) †
他のライブラリでも検証・復号化が可能かどうかは、
JSON Web Tokens - jwt.ioなどのサイトを使用して確認すると良い。
特定用途であれば、上記サイトにも.NETにも実装されている
- KeyedHashAlgorithm?
- RS256(HMAC using SHA-256 hash)
- AsymmetricAlgorithm?
- RS256(RSA using SHA-256 hash)
を使用すると良い。
認証であれば公開鍵暗号化方式のRS256(RSA using SHA-256 hash)が良い。
実装の脆弱性 †
実装の脆弱性に注意する。
参考 †
RFC †
JOSE WG †
jose : Javascript Object Signing and Encryption
OAuth WG †
Tags: :認証基盤, :クレームベース認証