- 追加された行はこの色です。
- 削除された行はこの色です。
「[[マイクロソフト系技術情報 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の基本的なヘッダには、
**[[JOSEヘッダ>JWT#m9c6f99a]] [#u5c396b1]
JWSの基本的なヘッダには、以下のものがある。
-秘密鍵で検証可能なHS256(HMAC using SHA-256 hash)
***RS256 [#tfe21b87]
秘密鍵で検証可能なHS256(HMAC using SHA-256 hash)
{
"alg": "HS256",
"typ": "JWT"
}
-公開鍵で検証可能なRS256(RSA using SHA-256 hash)
***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"
}
**[[ペイロード(クレームセット)>JWT#m5b94cda]] [#h15b0503]
***[[JWK]]をサポートする場合 [#tc7fd975]
jwkや、kid & jkuなどのパラメタを追加する。
**署名 [#f7edb04c]
**[[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]
[[ヘッダ>#u5c396b1]]、[[ペイロード(クレームセット)>#h15b0503]]、[[署名>#f7edb04c]]を以下のように[[表現(エンコード)>#xd09f92e]]したもの。
**表現(エンコード) [#xd09f92e]
以下の2つの表現(エンコード)方法がある。
-[[構成要素>#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)による署名を行う。
公開鍵暗号方式である、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付与
キー付きハッシュである、alg=HS256(HMAC-SHA256)によるMAC付与
-フォーマット([[JWS Compact Serialization>#xe1c18e7]])
***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: [[:認証基盤]], [[:クレームベース認証]], [[:暗号化]]