「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>JWT]] * 目次 [#pd2a93b9] #contents *概要 [#c95ff4a8] -ざっくり言って「[[署名>#f7edb04c]]付きの JWT = JWS」 -JWT と言えば、だいたい、JWSの事を言う。 -JWSは、暗号化ではなく[[署名>#f7edb04c]]なので、JSON の中身は誰でも見られる。 -通常、発行者だけが秘密鍵で検証できるが、 --秘密鍵を使用すれば発行者だけが検証可能。 --公開鍵を使用すれば誰でも検証可能。 -[[OpenID Connect]]のID Tokenなどで利用されている。~ [[OAuth]]2のAccess Tokenとしても使用されている。 *構成要素 [#v48fc731] **[[ヘッダ>JWT#m9c6f99a]] [#u5c396b1] JWSの基本的なヘッダには、 -秘密鍵で検証可能なHS256(HMAC using SHA-256 hash) { "alg": "HS256", "typ": "JWT" } -公開鍵で検証可能なRS256(RSA using SHA-256 hash) { "alg": "RS256", "typ": "JWT" } などがある。 **[[ペイロード(クレームセット)>JWT#m5b94cda]] [#h15b0503] **署名 [#f7edb04c] -色々な暗号化アルゴリズムを使用して作成した署名 -署名の検証キーの共有方法には以下の方法が有る。 --検証用エンドポイントを使用する。 --[[JWK]]を使用する。 --[[X.509証明書>証明書]]を使用する。 -参考 : OpenID Connect の署名検証 - Carpe Diem~ http://christina04.hatenablog.com/entry/2015/01/27/131259 --検証方法①:Googleの検証用エンドポイントを利用する --検証方法②:IdP(Google)の提供している公開鍵を使って自分で検証する ---公開鍵①:[[JWK]](JSON Web Key)を使う ---公開鍵①:[[X.509証明書>証明書]]を使う *詳細 [#u6d67bd4] [[ヘッダ>#u5c396b1]]、[[ペイロード(クレームセット)>#h15b0503]]、[[署名>#f7edb04c]]を以下のように[[表現(エンコード)>#xd09f92e]]したもの。 **表現(エンコード) [#xd09f92e] 以下の2つの表現(エンコード)方法がある。 ***JWS Compact Serialization [#xe1c18e7] -[[署名>#f7edb04c]]付きのデータを JSON (の Base64 URL Encode) 形式で表現する。 -「Base64」ではなく「Base64 &color(red){URL};」なので「=」は含まれない。 ※ 殆どの場合、こちらが使用されている。 ***JWS JSON Serialization [#t41a19b3] -pure な JSON として表現されるフォーマット -URL-Safe でもなければコンパクトでもない。 -[[署名>#f7edb04c]]を複数持てるといった違いがある。 **アルゴリズム [#f133bbd2] 認証系であれば公開鍵暗号化方式のRS256(RSA using SHA-256 hash)が良い。 ***RS256 [#xe033b54] alg=RS256(RSA-SHA256)による署名を行う。 -フォーマット([[JWS Compact Serialization>#xe1c18e7]]) --[[ヘッダ>#u5c396b1]].[[ペイロード(クレームセット)>#h15b0503]].[[署名>#f7edb04c]] -- BASE64URL (UTF-8 (Header)) . BASE64URL (UTF-8 (Claim Set)) . BASE64URL (UTF-8 (Signature)) ***HS256 [#b8d0ee68] alg=HS256(HMAC-SHA256)によるMAC付与 -フォーマット([[JWS Compact Serialization>#xe1c18e7]]) *手順 [#e7dc0563] **作成 [#paf2520a] -[[ヘッダ>#u5c396b1]]を生成し、UTF-8のバイト文字列に変換し、BASE64urlエンコード。 -[[ペイロード(クレームセット)>#h15b0503]]を生成し、UTF-8のバイト文字列に変換し、BASE64urlエンコード。 -BASE64urlエンコード済みの[[ヘッダ>#u5c396b1]]と[[ペイロード(クレームセット)>#h15b0503]]を~ ピリオドで連結する、UTF-8バイト文字列に変換し、BASE64urlエンコード。 -上記をヘッダで指定した暗号化プロバイダで署名し、[[署名>#f7edb04c]]の要素を追加する。 **検証 [#ib69bb72] -JWSを[[ヘッダ>#u5c396b1]]、[[ペイロード(クレームセット)>#h15b0503]]、[[署名>#f7edb04c]]に分割しBASE64urlでデコード。 -[[ヘッダ>#u5c396b1]]から[[JWT]]の種類(JWS)、暗号化プロバイダを確認する。 -[[署名方法>#f7edb04c]](暗号化プロバイダ、キー)を考慮してJWSの検証を行なう。 -検証完了後、[[ペイロード(クレームセット)>#h15b0503]]内の有効期限の検証も行なう。 ***検証サイト [#s7ab5c53] [[下記参照>#ma412b10]] *自作ライブラリ [#a945c75c] **署名・暗号化アルゴリズム [#p4042a8b] [[ココ>.NETの署名・暗号化アルゴリズム]]の署名・暗号化アルゴリズムを使用すると良い。 ***KeyedHashAlgorithm [#a86f6259] -HS256(HMAC using SHA-256 hash) --HMACSHA256 クラス (System.Security.Cryptography)~ https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.hmacsha256.aspx ***AsymmetricAlgorithm [#oc7f2c3b] -RS256(RSA using SHA-256 hash) --RSACryptoServiceProvider クラス (System.Security.Cryptography)~ https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.rsacryptoserviceprovider.aspx --Using RSACryptoServiceProvider for RSA-SHA256 signatures – .NET Security Blog~ https://blogs.msdn.microsoft.com/shawnfa/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures/ **参考サイト [#e11d0494] 以下が参考になる。 -IdM実験室: [JWT/OAuth]Service Accountを使ってGoogle APIを利用する②~ http://idmlab.eidentity.jp/2015/01/jwtoauthservice-accountgoogle-api_5.html ココを見ると、 -{ alg = "RS256", typ = "JWT" }と言うヘッダで、 -RSACryptoServiceProvider + X509Certificate2の署名を行っており、 これで、実際にGoogle側での検証ができている。 **検証サイト [#ma412b10] 上記のように、RFCを正確に理解していないとJWTライブラリ作成は難しいが、~ [[JSON Web Tokens - jwt.io>https://jwt.io/]]などの検証サイトを使用して検証できれば、及第点に達していると言える。 以下のように検証できる。 ***手順 [#yf87387f] +左ペイン(Encoded)にJWTの文字列を貼り付ける。 +すると、入力したJWTから、ペイン(Dencoded)のHeader、Payloadに自動的に表示がなされる。 +次に、上部 ALGORITHM selectbox から、Headerに表示された"alg"と同じアルゴリズムを選択する。 +最後に、VERIFY SIGNATUREに、署名の検証に使用するキーを入力する([[HS256の場合>#b6059f50]]と[[RS256の場合>#hbd54613]]で異なる)。 ***HS256の場合 [#b6059f50] HS256は非常に単純で、署名に使用したキーのBase64(Base64Url)表現を指定する。 #ref(HS256.png,left,nowrap,HS256,50%) ***RS256の場合 [#hbd54613] RS256は署名に使用した秘密鍵に対応する公開鍵を指定する。~ 私は、[[X.509証明書>証明書]]を利用したので、[[OpenSSLで公開鍵を取得して>証明書#tb47e80e]]、それを貼り付けた所、検証ができた。~ ポイントは、 -「-----BEGIN PUBLIC KEY-----」 - 「公開鍵」 -「-----END PUBLIC KEY-----」 と、ヘッダ・フッタ部分も貼り付ける必要がある所だろうか。 #ref(RS256.png,left,nowrap,RS256,50%) ***Open棟梁 [#c4289f7f] -JWTの生成と検証 - Open 棟梁 Wiki~ https://opentouryo.osscons.jp/index.php?JWT%E3%81%AE%E7%94%9F%E6%88%90%E3%81%A8%E6%A4%9C%E8%A8%BC *参考 [#y2ab180f] -RFC 7515 - JSON Web Signature (JWS)~ https://tools.ietf.org/html/rfc7515 -JSON Web Signature (JWS) 日本語訳~ https://openid-foundation-japan.github.io/draft-ietf-jose-json-web-signature-14.ja.html -複雑に関係しあうJWTまわりの仕様を見る: JWS (JSON Web Signature) - 理系学生日記~ http://kiririmode.hatenablog.jp/entry/20170225/1488020088 **[[JWA - JWS用>JWA#zcf6ef0e]] [#xd6c0477] ---- Tags: [[:認証基盤]], [[:クレームベース認証]], [[:暗号化]]