「[[マイクロソフト系技術情報 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] **[[JOSEヘッダ>JWT#m9c6f99a]] [#u5c396b1] JWSの基本的なヘッダには、以下のものがある。 ***RS256 [#tfe21b87] 秘密鍵で検証可能なHS256(HMAC using SHA-256 hash) { "alg": "HS256", "typ": "JWT" } ***HS256 [#k5878e6c] 公開鍵で検証可能なRS256(RSA using SHA-256 hash) { "alg": "RS256", "typ": "JWT" } ***ES256 [#v4db663d] 公開鍵で検証可能なES256(ECDSA using P-256 and SHA-256) { "alg": "ES256", "typ": "JWT" } ***[[JWK]]をサポートする場合 [#tc7fd975] jwkや、kid & jkuなどのパラメタを追加する。 **[[JWSペイロード(クレームセット)>JWT#m5b94cda]] [#h15b0503] **JWS署名 [#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] **表現(エンコード) [#xd09f92e] -[[構成要素>#v48fc731]]([[ヘッダ>#u5c396b1]]、[[ペイロード(クレームセット)>#h15b0503]]、[[署名>#f7edb04c]])を以下のように表現(エンコード)したもの。 -以下の2つの表現(エンコード)方法があり、どちらでも、[[構成要素>#v48fc731]]は、base64urlでエンコードされる。 ***JWS Compact Serialization [#xe1c18e7] -[[署名>#f7edb04c]]付きのデータを JSON (の Base64 URL Encode) 形式で表現する。 -「Base64」ではなく「Base64 &color(red){URL};」なので「=」は含まれない。 -例 --[[ヘッダ>#u5c396b1]].[[ペイロード(クレームセット)>#h15b0503]].[[署名>#f7edb04c]] -- BASE64URL (UTF-8 (Header)) . BASE64URL (UTF-8 (Claim Set)) . BASE64URL (UTF-8 (Signature)) ※ 殆どの場合、こちらが使用されている。 ***JWS JSON Serialization [#t41a19b3] あまり市民権を獲得しているようには思えない表現(エンコード)。 -pure な JSON として表現されるフォーマット -URL-Safe でもなければコンパクトでもない。 -[[署名>#f7edb04c]]を複数持てるといった違いがある。 -Syntax of a JWS using the general JWS JSON Serialization { "payload":"<payload contents>", "signatures":[ {"protected":"<integrity-protected header 1 contents>", "header":<non-integrity-protected header 1 contents>, "signature":"<signature 1 contents>"}, ... {"protected":"<integrity-protected header N contents>", "header":<non-integrity-protected header N contents>, "signature":"<signature N contents>"}] } -Example --Complete JWS JSON Serialization Representation { "payload": "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGF tcGxlLmNvbS9pc19yb290Ijp0cnVlfQ", "signatures":[ {"protected":"eyJhbGciOiJSUzI1NiJ9", "header": {"kid":"2010-12-29"}, "signature": "cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZ mh7AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjb KBYNX4BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHl b1L07Qe7K0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZES c6BfI7noOPqvhJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AX LIhWkWywlVmtVrBp0igcN_IoypGlUPQGe77Rw"}, {"protected":"eyJhbGciOiJFUzI1NiJ9", "header": {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"}, "signature": "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8IS lSApmWQxfKTUJqPP3-Kg6NU1Q"}] } --JWS Using Flattened JWS JSON Serialization { "payload": "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGF tcGxlLmNvbS9pc19yb290Ijp0cnVlfQ", "protected":"eyJhbGciOiJFUzI1NiJ9", "header": {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"}, "signature": "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8IS lSApmWQxfKTUJqPP3-Kg6NU1Q" } **アルゴリズム [#f133bbd2] 認証系であれば公開鍵暗号化方式のRS256(RSA using SHA-256 hash)が良い。 ***RS256 [#xe033b54] 公開鍵暗号方式である、alg=RS256(RSA-SHA256)による署名を行う。 ***HS256 [#b8d0ee68] キー付きハッシュである、alg=HS256(HMAC-SHA256)によるMAC付与 ***ES256 [#b8d0ee68] 公開鍵暗号方式である、alg=ES256(ECDSA using P-256 and SHA-256)による署名を行う。 -WebCrypto APIでECDSAの署名と検証を試してみる~ https://qiita.com/tomoyukilabs/items/b346a71a920eb7a93501 *手順 [#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/ -ES256(ECDSA using P-256 and SHA-256) --ECDsa クラス (System.Security.Cryptography)~ https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.ecdsa.aspx **参考サイト [#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] **[[暗号化アルゴリズム]] [#gc5974cd] ***[[.NETの署名・暗号化アルゴリズム]] [#db2f0e77] ---- Tags: [[:認証基盤]], [[:クレームベース認証]], [[:暗号化]]