「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
以下の内容で最終確認済み。
https://tools.ietf.org/html/rfc7515
- ざっくり言って「MACや署名付きの JWT = JWS」
- JWT と言えば、だいたい、JWSの事を言う。
- JWSは、暗号化ではなく署名なので、JSON の中身は誰でも見られる。
- 通常、発行者だけが秘密鍵で検証できるが、
- 秘密鍵を使用すれば発行者だけが検証可能。
- 公開鍵を使用すれば誰でも検証可能。
構成要素 †
JWSの基本的なヘッダ(≒JWS Compact Serializationの場合の保護ヘッダ)には、以下のものがある。
ヘッダの例 †
追加のパラメタ †
- JWKをサポートする場合
jwk, kid & jkuなどのパラメタを追加する。
- 証明書をサポートする場合
- x5u(X.509 URL)ヘッダ・パラメタ
PEMエンコーディング
- x5c(X.509証明書チェーン)ヘッダ・パラメタ
DERエンコーディングのbase64url
- x5t(X.509証明書SHA-1拇印)ヘッダ・パラメタ
DERエンコーディングのbase64url
- x5t#S256(X.509証明書SHA-256拇印)
DERエンコーディングのbase64url
TLS要件 †
"jku" and / or "x5u"ヘッダパラメタをサポートする実装は、TLSが必要。
署名 †
- 色々な暗号化アルゴリズムを使用して作成した署名
- 署名の検証キーの共有方法には以下の方法が有る。
詳細 †
表現(エンコード) †
JWS Compact Serialization †
多くの場合は、この表現(エンコード)。
- 署名付きのデータを JSON (の Base64 URL Encode) 形式で表現する。
- 「Base64」ではなく「Base64 URL」なので「=」は含まれない。
※ 殆どの場合、こちらが使用されている。
JWS JSON Serialization †
- あまり市民権を獲得しているようには思えない表現(エンコード)。
- pure な JSON として表現されるフォーマット
- URL-Safe でもなければコンパクトでもない。
- MACや署名を複数持てるといった違いがある。
- Syntax
- "protected" = BASE64URL(UTF8(保護ヘッダ))
- "signatures"
- "header" = 非保護ヘッダ(JSON)
- "payload" = BASE64URL(ペイロード(クレームセット))
- "signature" = BASE64URL(署名)
{
"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
MACや署名が 1 つのみの場合は Flattened JWS JSON Serialization を使える。
{
"payload":
"eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGF
tcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
"protected":"eyJhbGciOiJFUzI1NiJ9",
"header":
{"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"},
"signature":
"DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8IS
lSApmWQxfKTUJqPP3-Kg6NU1Q"
}
保護ヘッダ・非保護ヘッダ †
JOSEヘッダは、以下のメンバの和集合。
保護ヘッダ †
MACや署名によって完全性が保護されているヘッダ・パラメタを含むJSONオブジェクト。
非保護ヘッダ †
- 完全性保護されていないヘッダ・パラメタを含むJSONオブジェクト。
- 用例を解析してみると、JOSEヘッダ中の"kid"パラメタが抽出されている。
(...kidが改ざんされると検証できなくなるだけなので、保護しなくてもイイためとは言えそう)
アルゴリズム †
認証系であれば公開鍵暗号化方式のRS256(RSA using SHA-256 hash)が良い。
キー付きハッシュである、alg=HS256(HMAC-SHA256)によるMAC付与
公開鍵暗号方式である、alg=RS256(RSA-SHA256)による署名を行う。
公開鍵暗号方式である、alg=ES256(ECDSA using P-256 and SHA-256)による署名を行う。
手順 †
作成 †
JWS Compact Serializationとの差異は以下。
検証 †
JWS Compact Serializationとの差異は以下。
検証サイト †
下記参照
具体例 †
HS256 †
https://tools.ietf.org/html/rfc7515#appendix-A.1
RS256 †
https://tools.ietf.org/html/rfc7515#appendix-A.2
ES256 †
https://tools.ietf.org/html/rfc7515#appendix-A.3
セキュリティに関する考慮事項 †
鍵エントロピー †
すべての鍵に最低128ビットのエントロピーを使用する必要がある。
コンテキスト次第で、さらに多くのエントロピーが必要になる可能性がある。
ランダム値 †
- パブリック/プライベートキーペア、MACキー、パディング値をランダムに生成する必要がある。
- 暗号鍵を生成するために適切な擬似乱数生成器(PRNG)を使用する。
(.NETでは、PRNGとして、RNGCryptoServiceProviderを使用する。)
鍵の識別 †
仕様の外だが、以下を使用できる。
鍵の保護、発信元認証 †
MAC †
- 保護
- MACキーを保護する必要がある。
- MACキーが破損すると、認証されたコンテンツの変更が検出されなくなる可能性がある。
署名 †
- 保護
- 秘密鍵を保護する必要がある。
- 署名者の秘密鍵が侵害されると、攻撃者は署名者になりすますことができる。
署名とMACの違い †
- 共通点
- 完全性チェックを提供
完全性値が計算されてからメッセージが変更されていないことを確認
- 相違点
セキュリティプロパティにはいくつかの重要な違いがある。
- 特定の状況下でのみ発信識別を提供するため、
第三者への発信を証明するために使用できない。
- MACキーが2つのエンティティにしか知られておらず、受信者がメッセージを作成していないことが分かっている場合にのみ発信を判断できる。
- これは、メッセージが対称MACキーを知っている当事者のうちの1つによって生成されたという裏付けを提供するだけ。
- 秘密鍵とMACキー
- 秘密鍵
単一のエンティティの手元にある
- MACキー
整合性の計算と検査にMACキーを使用するすべてのエンティティの手元にある必要がある。
※ HS256はプレーンなHMACでMACではない(ややこしい)。
暗号の敏捷性 †
JWAを参照
自作ライブラリ †
署名・暗号化アルゴリズム †
ココの署名・暗号化アルゴリズムを使用すると良い。
KeyedHashAlgorithm? †
- HS256(HMAC using SHA-256 hash)
AsymmetricAlgorithm? †
- RS256(RSA using SHA-256 hash)
- ES256(ECDSA using P-256 and SHA-256)
- PS256(RSASSA-PSS using SHA-256 and MGF1 with SHA-256)
参考サイト †
以下が参考になる。
ココを見ると、
- { alg = "RS256", typ = "JWT" }と言うヘッダで、
- RSACryptoServiceProvider? + X509Certificate2の署名を行っており、
これで、実際にGoogle側での検証ができている。
検証サイト †
上記のように、RFCを正確に理解していないとJWTライブラリ作成は難しいが、
JSON Web Tokens - jwt.ioなどの検証サイトを使用して検証できれば、及第点に達していると言える。
以下のように検証できる。
手順 †
- 左ペイン(Encoded)にJWTの文字列を貼り付ける。
- すると、入力したJWTから、ペイン(Dencoded)のHeader、Payloadに自動的に表示がなされる。
- 次に、上部 ALGORITHM selectbox から、Headerに表示された"alg"と同じアルゴリズムを選択する。
- 最後に、VERIFY SIGNATUREに、署名の検証に使用するキーを入力する(HS256の場合とRS256の場合で異なる)。
HS256の場合 †
HS256は非常に単純で、署名に使用したキーのBase64(Base64Url)表現を指定する。
RS256の場合 †
RS256は署名に使用した秘密鍵に対応する公開鍵を指定する。
私は、X.509証明書を利用したので、OpenSSLで公開鍵を取得して、それを貼り付けた所、検証ができた。
ポイントは、
- 「-----BEGIN PUBLIC KEY-----」
- 「公開鍵」
- 「-----END PUBLIC KEY-----」
と、ヘッダ・フッタ部分も貼り付ける必要がある所だろうか。
Open棟梁 †
参考 †
Tags: :IT国際標準, :プログラミング, :通信技術, :認証基盤, :クレームベース認証, :暗号化