JWT: どの署名アルゴリズムを使用すればよいですか?

JWT: どの署名アルゴリズムを使用すればよいですか?

[[421048]]

この記事は、Scott Brady が執筆した WeChat パブリック アカウント「DotNET Technology Circle」から転載したものです。この記事を転載する場合は、DotNET Technology Circle 公式アカウントまでご連絡ください。

JWT: どの署名アルゴリズムを使用すればよいですか?

JSON Web Token (JWT) は、RS256、PS512、ES384、HS1 など、さまざまなアルゴリズムを使用して署名できます。どのアルゴリズムを使用するかを尋ねられたときに、一部の開発者が頭を悩ませるのも理解できます。

私の経験では、多くの主要な ID プロバイダーは歴史的に RS256 のみを提供してきたか、少なくともデフォルトでそれを使用してきました。ただし、オープン バンキングなどの取り組みにより、これらの ID プロバイダーは現在、より多くの署名アルゴリズムをカバーするようにサポートを拡大しており、どのアルゴリズムを使用するかを理解する必要があります。

私は暗号学者ではありませんが、OpenID Connect と FIDO2 の仕事を通じて、さまざまな署名アルゴリズムと、各アルゴリズムに対する暗号コミュニティの全体的な考え方について、実践者としての理解を深めました。この記事では、各「alg」値の意味を理解し、利用可能な最適な署名アルゴリズムを選択できるようにするための知識を提供します。

TL;DR: EdDSA > ECDSA または RSASSA-PSS > RSASSA-PKCS1-v1_5 で、何を期待するかがわかります。

アルゴリズム (alg) 値

署名アルゴリズムの各ファミリを見る前に、まず「alg」値 (例: RS256) の意味を明確にしましょう。これらは、JavaScript Object Signing and Encryption (JOSE) ファミリーの一部である JSON Web Algorithms (JWA) です。 JWT ヘッダーには、JWT がどのように署名されたかを示す「alg」値が表示され、JSON Web Keys (JWK) には、キーがどのアルゴリズムに使用されたかを示す値が表示されます。

一般的な経験則として、「alg」値は次のように分類できます。

RS

256

署名アルゴリズム

ハッシュアルゴリズム

  • 署名アルゴリズム ファミリ: この場合、RS は RSASSA-PKCS1-v1_5 を意味します。
  • 署名アルゴリズムで使用されるハッシュ アルゴリズム。この場合、256 は SHA-256 を意味します。

ほとんどの署名アルゴリズムには、SHA-256、SHA-384、SHA-512 のバリエーションがあります。場合によっては、SHA-1 ?? を使用し、FIDO2 準拠に必要な「RS1」のようなものを使用することもできます。

これらのアルゴリズムは一般的にRFC 7518 [1]で定義されていますが、サポートされているアルゴリズムの完全なリストはJOSE IANAレジストリ [2]で確認できます。

どのハッシュアルゴリズムを使用すればよいですか?

SHA-256、SHA-384、および SHA-512 はすべて、同じハッシュ アルゴリズム ファミリである SHA-2 のバリエーションです。

経験則として、アルゴリズム内の数字は、生成されるハッシュのサイズを表します。たとえば、SHA-256 は 256 ビットのハッシュ値を生成しますが、SHA-512 は 512 ビットのハッシュ値を生成します。

それぞれ出力サイズの 50% のセキュリティ レベルを提供します。つまり、SHA-256 では 128 ビットのセキュリティが提供され、SHA-512 では 256 ビットのセキュリティが提供されます。これは、誕生日の制限[3]により、攻撃者が衝突を見つけ始める前に2^128個のハッシュ値を生成しなければならないことを意味します。そのため、最低でも 128 ビットのセキュリティを使用します。

すぐに SHA-256 よりも優れたものが必要になることはありません。 SHA-1 は使用しないでください。

検証: アルゴリズムを理解する

JWT 署名を検証する各アプリケーションは、どのようなアルゴリズムを期待するか、どのキーを使用するかを事前に正確に把握する必要があります。これは、各公開キーをアルゴリズムに割り当てることによって実行できます (たとえば、このキーは RS384 用、このキーは ES256 用)。 1 つのアルゴリズムに複数のキーがある場合は、kidJWT ヘッダーのキー ID ( ) を使用して、どのキーを使用するかを知ることができます。

基本的には、JWT 内の kid と alg の値が期待どおりに一致することを確認する必要があります。一致しない場合は、誰かが悪いです。

  1. {
  2. 「タイプ」 「JWT」 ​​、
  3. "kid" : "123" , //このキー...
  4. "alg" : "RS256" // ...このアルゴリズム使用できますか?
  5. }

OpenID Connect などのプロトコルは、TLS で保護されたエンドポイントで利用可能な検出ドキュメントと JSON Web Key Sets (JWKS) を使用してこれを実現します。

ここで、JWT ヘッダーの「alg」値を信頼するだけでなく、「none」アルゴリズムの JWT や、ヘッダーに公開キーが埋め込まれた JWT を受け入れないようにしてください。

RSASSA-PKCS1-v1_5 (例: RS256)

RS256 = RSASSA-PKCS1-v1_5 は SHA-256 を使用します

RS AES -PKCS1-v1_5 は暗号化には安全ではなくなりましたが、RSA SSA -PKCS1-v1_5 は依然としてデジタル署名に適しています。先ほど述べたように、私の経験では、RS256 は歴史的にほとんどの JWT 実装のデフォルトであり、多くの SaaS ID プロバイダーはこの署名アルゴリズムのみを提供しています。 RS256 で署名された JWT をサポートしていないシステムを見つけるのは困難です。

RSASSA-PKCS1-v1_5 を使用して署名された JWT には決定論的な署名があり、同じ JWT ヘッダーとペイロードでは常に同じ署名が生成されます。

RSASSA-PKCS1-v1_5 は長い間使用されてきましたが、現在では一般的に RSASSA-PSS (確率的署名を備えた RSA) が推奨されます。これは、RSASSA-PKCS1-v1_5 が壊れていると言っているわけではなく、RSASSA-PSS には他のものにはない望ましい機能があるだけだと言っているのです。実際、RFC 8017 では、RSA で署名する場合に RSASSA-PSS が必須とされています。

RSASSA-PKCS1-v1_5 に対する既知の攻撃はありませんが、堅牢性を向上させるために新しいアプリケーションでは RSASSA-PSS が必要です。

RFC8017[4]

そうは言っても、Bleichenbacher[5]によるRSA PKCS#1暗号化および署名標準[6]への攻撃について議論しているとき、David WongはReal-Word Cryptography[7]で興味深い統計を共有しました。

暗号化アルゴリズムを完全に破壊する最初の攻撃とは異なり、2 番目の攻撃は実装攻撃(署名検証に対する攻撃)です。つまり、署名スキームが(仕様に従って)正しく実装されていれば、攻撃は機能しません。

しかし、2019年に[8]、署名用のRSA PKCS#1 v1.5のオープンソース実装の多くが実際にこの罠に陥り、標準を誤って実装したため、Bleichenbacherの偽造攻撃のさまざまなバリエーションが機能する可能性があることが示されました。

現実世界の暗号[9]

この攻撃は署名検証に対するものであるため、JWT を検証するすべての受信者が Bleichenbacher 攻撃に対して脆弱ではないライブラリを使用していることを確信する必要があります。多くの第三者と取引している場合は困難になります。

OpenID の Financial API (FAPI) などのオープン バンキングの回避策では、RSASSA-PKCS1-v1_5 の使用は許可されません。私の常連読者にとって、これは IdentityServer4 バージョン 3 まで IdentityServer で使用できる唯一のアルゴリズムでした。

さらに読む

OpenSSLを使用してJWT署名用のRSAキーを生成する方法を学ぶ[10]

RSASSA-PSS (例: PS256)

PS256 = SHA-256 と MGF1 と SHA-256 を使用した RSASSA-PSS

RSASSA-PSS は、同じ JWT ヘッダーとペイロードから毎回異なる署名が生成される RSA の確率バージョンです。他のアルゴリズムとは異なり、これはせいぜい確率的なアプローチです。署名生成中にランダムな値を使用することもできますが、セキュリティにとって重要ではありません。一般的に、実装がはるかに簡単なので、間違いが起きにくくなります。

RSA キーを使用する場合は、RSASSA-PKCS1-v1_5 ではなく RSASSA-PSS を使用することをお勧めしますが、幸いなことに、RSA キーはどちらの署名方式でも使用できます。署名の長さも両者で同じです。

英国のオープンバンキングでは当初 PS256 の使用が義務付けられていましたが、後に ES256 にも開放されました。

さらに読む

  • RSASSA-PSSの詳細と.NET Coreでの使用方法について学ぶ[11]
  • OpenSSLを使用してJWT署名用のRSAキーを生成する方法を学ぶ[12]

ECDSA (例: ES256)

ES256 = P-256 と SHA-256 を使用した ECDSA

楕円曲線デジタル署名アルゴリズム (ECDSA) の場合、ハッシュ アルゴリズムを示す ES256 の数字も曲線に関連しています。 ES256 は P-256 (secp256r1、別名 prime256v1) を使用し、ES384 は P-384 (secp384r1) を使用し、奇妙なことに、ES512 は P-521 (secp521r1) を使用します。はい、521です。はい、マイクロソフト[13]でさえ間違っていました。

楕円曲線暗号 (ECC) は RSA より解読がはるかに困難です (あるいは、私たちは RSA を解読するのが本当に得意なのかもしれません)。したがって、ECDSA では RSA よりもはるかに短いキーと署名を使用できます。約 256 ビットの短い楕円曲線 (EC) キーは、3072 ビットの RSA キーと同じセキュリティを提供します。

ECDSA は RSA の同等のものよりも高速であるとよく記載されていますが、これは署名の生成にのみ適用され、署名の検証は一般に RSA の方が高速です。 JWT を使用すると、1 回署名して複数回検証することになります。

ECDSA で署名された JWT には確率的署名があり、同じ JWT ヘッダーとペイロードでは常に異なる署名が生成されます。しかし残念なことに、ECDSA は悪い意味で確率的であり、署名のセキュリティにはランダム性の生成が不可欠です。

ECDSA では、署名ごとに 1 回だけ生成される乱数を使用します。ランダムな値を一度だけ使用しないと、ソニーのプレイステーション3やビットコインで実証されているように、秘密鍵が簡単に復元可能になる可能性があります[14]。 PlayStation 3 の場合、静的乱数により秘密鍵が復元されましたが、Bitcoin の場合、Android ユーザーは Android 上の Java の SecureRandom クラスのバグの影響を受けていました。確率的署名のセキュリティにランダムな値が必要な場合は、ランダムな値を必要としない決定論的署名を優先する必要があります。

RSASSA-PKCS1-v1_5 には署名検証に関する問題があり、ECDSA には署名生成に関する問題がありますが、トークン発行者の場合は対処が容易です。

ECDSA は人気が高まっていますが、楕円曲線暗号の実装方法や、ランダム値の使用による実装の難しさに対する懸念から、暗号学者からは一般的に反対の声が上がっているようです。 RSA よりも評判は良いですが、暗号専門家は依然として EdDSA への移行を推奨しています。

JOSE はもともと NIST によって定義された曲線を使用していました。 NIST によって定義された曲線を使用することに不安があり、ECDSA を使用したい場合は、secp256r1 ではなく secp256k1 などの Koblitz 曲線を使用するのが一般的な代替手段です。 Kobiltz 曲線は若干弱いですが、NIST 曲線で使用されている説明のつかない乱数が NSA の別のバックドアを示しているのではないかと懸念している場合、Kobiltz 曲線はますます人気が高まっている代替手段となります。これらの曲線は、Bitcoin、Ethereum、FIDO2 で使用されています。ただし、NIST 以外の曲線を使用する場合は、EdDSA を使用する必要があります。 JOSE では、Kobiltz を使用するアルゴリズムは ES256K のように K で終わります。

さらに読む

  • .NET CoreでECDSAを使用する方法[15]とIdentityServer4でECDSAを使用してトークンに署名する方法[16]を学ぶ
  • OpenSSLを使用してJWT署名用のECキーを生成する方法を学びます。[17]
  • .NET CoreでのカスタムJWT署名アルゴリズムの使用と、Kobiltz曲線を使用した例[18]

エドDSA

EdDSA = EdDSA署名アルゴリズムが使用される

EdDSA は以前のアルゴリズムの傾向に反し、単一の alg 値を使用します。代わりに、事前に合意されたキーを使用して CRV で定義された曲線に依存します。

たとえば、EdDSA 公開鍵を含む JWK は次のようになります。

  1. {
  2. 「kty」 : 「OKP」
  3. "alg" : "EdDSA"
  4. "crv" : "Ed25519"
  5. "x" : "60mR98SQlHUSeLeIu7TeJBTLRG10qlcDLU4AJjQdqMQ"  
  6. }

これにより、最新の動作では JWT ではなくキーに割り当てられた曲線が強制的に使用され、さまざまな ALG 関連の攻撃が排除されます。

EdDSA は、ねじれたエドワーズ曲線を利用する楕円曲線暗号の一種です。これは、Schnorr 署名システム (DSA ではありません) のバリエーションです。 EdDSA は署名と検証の両方が高速で、署名が短く、あらゆる種類のセキュリティ脆弱性を回避します。

RFC 8037 では、次の EdDSA バリアントに対する JOSE サポートが定義されています。

  • Ed25519: 255 ビット Curve25519 (3​​2 バイトの秘密鍵、32 バイトの公開鍵、64 バイトの署名)。署名には SHA-512 を使用します。 128ビットのセキュリティを提供
  • Ed448: 448 ビット Curve448-Goldilocks (57 バイトの秘密鍵、57 バイトの公開鍵、114 バイトの署名)。署名にはSHAKE256を使用します。 224ビットのセキュリティを提供

EdDSA で署名された JWT には決定論的な署名があり、同じ JWT ヘッダーとペイロードでは常に同じ署名が生成されます。これは、秘密鍵を保護するためにランダムな nonce 値に依存する問題を解決する、優れた決定論的アプローチです。 EdDSA は秘密鍵の作成時にのみランダム値を使用します。これはJOSEとJWTの批評家によって推奨されているアルゴリズムです[19]。

JWT ライブラリでの EdDSA のサポートは少し不完全ですが、近いうちにさらにサポートが拡大される予定です。

さらに読む

  • EdDSAの詳細と.NET Coreでの使用方法について学ぶ[20]
  • EdDSA を使い始める[21]ScottBrady.IdentityModel を使用した .NET Core での JWT 署名[22]
  • EdDSAの設計上の利点についてはcr.yp.to [23]で詳しく読む

HMAC (例: HS256)

HS256 = SHA-256 を使用した HMAC

これまでは、トークン発行者だけが署名を作成する秘密鍵を持ち、他の全員は署名の検証に使用できる対応する公開鍵を持つ非対称暗号化について説明してきました。たとえば、アイデンティティ プロバイダーは秘密鍵を保持し、証明書利用者は公開鍵を使用します。

まれに、トークンを発行して検証する唯一のユーザーである場合は、対称暗号化と HS256 のようなものの使用を検討できます。 これは、署名の作成と検証に同じキーを使用します。

私の意見では、このような状況に陥った場合、JWT は適切なソリューションではないと思います。同じエンティティが読み取りと書き込みの両方を実行している場合、JWT 内の構造化されたプレーンテキスト データをラウンドトリップするための要件は何ですか? データをデータベースに保存して参照を渡すか、Branca トークンや JSON Web Encryption (JWE) などを使用して、自分だけがデータを読み取れるようにすることをお勧めします。

一般的に、JWT 署名に HMAC を使用することはアンチパターンと見なされます。

さらに読む

  • JWEと.NET Coreでの使用方法について詳しくは[24]をご覧ください。
  • ScottBrady.IdentityModelでBrancaトークン[25]を使用する方法を学ぶ

暗号化を一切使用していない?

なし = base64 エンコード

すみません、仕方がありませんでした。使用しないでください。

提案

可能な場合は EdDSA を使用し、そうでない場合は ECDSA を使用します。 RSA を使用する必要がある場合は、RSASSA-PKCS1-v1_5 よりも RSASSA-PSS を優先してください。

RSA が徐々に消滅しつつあると言っても、議論の余地はないと思います。現在、ECDSA を提供することは良い選択肢ですが、理想的には可能な限り EdDSA を使用することが望まれます。

ただし、どのアルゴリズムを使用する場合でも、どのアルゴリズムを期待するか、および認証にどのキーを使用するかを事前に把握しておく必要があります。

参考文献

[1] RFC 7518より: https://tools.ietf.org/html/rfc7518

[2] JOSE IANAレジストリ: https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms

[3] 誕生日の境界: https://en.wikipedia.org/wiki/Birthday_attack

[4] RFC 8017: https://tools.ietf.org/html/rfc8017

[5] ブライヘンバッハー: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher

[6] 攻撃: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher

[7] リアルワールド暗号: https://www.manning.com/books/real-world-cryptography

[8] 2019年: https://www.cs.purdue.edu/homes/schau/files/pkcs1v1_5-ndss19.pdf

[9] 現実世界の暗号: https://www.manning.com/books/real-world-cryptography

[10] RSAキーの生成: https://www.scottbrady91.com/OpenSSL/Creating-RSA-Keys-using-OpenSSL

[11] RSASSA-PSSと.NET Coreでの使用方法: https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-RSASSA-PSS-in-dotnet-Core

[12] RSAキーを生成する: https://www.scottbrady91.com/OpenSSL/Creating-RSA-Keys-using-OpenSSL

[13] マイクロソフトでも: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/Microsoft.IdentityModel.Tokens/JsonWebKeyECTypes.cs#L40

[14] ソニーのプレイステーション3とビットコイン: https://medium.com/asecuritysite-when-bob-met-alice/not-playing-randomly-the-sony-ps3-and-bitcoin-crypto-hacks-c1fe92bea9bc

[15] .NET CoreでECDSAを使用する方法: https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-ECDSA-in-dotnet-Core

[16] IdentityServer4でECDSAを使用してトークンに署名する: https://www.scottbrady91.com/Identity-Server/Using-ECDSA-in-IdentityServer4

[17] ECキーの生成: https://www.scottbrady91.com/OpenSSL/Creating-Elliptical-Curve-Keys-using-OpenSSL

[18] コビルツ曲線を使用した例: https://www.scottbrady91.com/C-Sharp/Supporting-Custom-JWT-Signing-Algorithms-in-dotnet-Core

[19] JOSEとJWTの批評家は以下を推奨している: https://www.scottbrady91.com/JOSE/Alternatives-to-JWTs

[20] EdDSAと.NET Coreでの使用方法: https://www.scottbrady91.com/C-Sharp/EdDSA-for-JWT-Signing-in-dotnet-Core

[21] EdDSAを使い始める: https://github.com/scottbrady91/IdentityModel

[22] JWT署名用のScottBrady.IdentityModel: https://github.com/scottbrady91/IdentityModel

[23] cr.yp.to: https://ed25519.cr.yp.to/

[24] JWEと.NET Coreでの使用方法: https://www.scottbrady91.com/C-Sharp/JSON-Web-Encryption-JWE-in-dotnet-Core

[25] Brancaトークンの使用方法: https://www.scottbrady91.com/C-Sharp/Replacing-JWTs-with-Branca-and-PASETO-in-dotnet-Core

<<:  二度とアルゴリズムの罠に陥らないでください!背後にいる人物を見つけ出す

>>:  人工知能の発展には限界が必要

ブログ    
ブログ    

推薦する

統計分析と人工知能の9つの有名な大惨事

2017年、『エコノミスト』誌は、石油ではなくデータが世界で最も価値のある資源になったと宣言しました...

AIコンピューティングパワーギャップを越えて、人工知能コンピューティングセンターの産業的価値が強調される

「第14次5カ年計画」の骨子には「デジタル化の加速とデジタル中国の構築」という独立した章が設けられ、...

保存しておくべき機械学習チートシート 27 選

機械学習にはさまざまな側面があり、調査を始めたときに、特定のトピックの要点を簡潔にリストしたさまざま...

GitHub のホット プロジェクト: 実稼働レベルのディープラーニング プロジェクトを構築するには?

ディープラーニング モデルを本番環境に導入することは、優れたパフォーマンスのモデルをトレーニングする...

データサイエンスと人工知能の専門家がプログラミングスキルを向上させる方法

[[379310]]ビッグデータダイジェスト制作出典: medium編集者: Hippoプログラミン...

自動運転車の「おとぎ話」にはどんな本当のチャンスが隠されているのでしょうか?

[[186930]]次に最も重要なテクノロジーは何でしょうか? 多くの人が「人工知能、VR、自動運...

Huawei の徐文偉氏: インテリジェントな未来を構想する (HC カンファレンス PPT + スピーチ全文)

第3回HUAWEI CONNECT 2018が2018年10月10日に上海万博展示コンベンションセン...

AIが5分で「3D展示」を完成させる「魔法の博物館」を制作

よく見てください、ここはメカスーツまで多種多様な展示品がある「魔法博物館」です...魔法の鏡、クリス...

ひと口引くとバラが生き返ります! Googleは画像ダイナミクスを生成することを提案しており、すべてのものに魂が宿ることになる

ほら、軽く引っ張るとバラが動きますよ。葉を左にドラッグすると、松の木も同じ方向に移動します。引っ張る...

機械学習がデータセンター管理をどう変えるか

機械学習はデータセンターの経済性を劇的に変え、将来の改善への道を開きます。機械学習と人工知能がデータ...

...

自然言語処理がビジネスインテリジェンスの未来である理由

[[187102]] Siri に道順を尋ねるたびに、複雑なコード列がアクティブ化され、「Siri」...

実践的なスキル: システムレベルからディープラーニングコンピューティングを最適化するにはどうすればよいでしょうか?

画像、音声認識、自然言語処理、強化学習などの多くの技術分野において、ディープラーニングは非常に効果的...

ガートナーの2020年人工知能技術ハイプサイクルを通して新たな変化を見る

ガートナーの最近の調査によると、企業の47%が流行の発生以来人工知能(AI)への投資を維持しており、...

...