ドキュメント

§暗号化移行ガイド

Play 1.x から、Play にはいくつかの暗号化操作を提供する Crypto オブジェクトが付属していました。これは Play の内部で使用されていました。Crypto オブジェクトはドキュメントには記載されていませんが、scaladoc では「暗号化ユーティリティ」として記載されています。

「これらのユーティリティは便宜のために意図されていますが、各メソッドのドキュメントを読み、このクラスを正しく使用するには暗号化の背後にある概念を理解することが重要です。安全な暗号化は難しく、暗号化の十分な理解に代わるものはありません。これらのメソッドは、すべての暗号化ニーズに適しているわけではありません。」

様々な理由から、便宜のために暗号化ユーティリティを提供することは実現不可能であることがわかりました。2.5.x では、Play 固有の機能は `CookieSigner`、`CSRFTokenSigner`、`AESSigner` トレイトに分割され、`Crypto` シングルトンオブジェクトは非推奨になりました。

このドキュメントの残りの部分では、Crypto の背後にある内部機能、暗号化操作の適合性(および不適合性)、および Crypto 機能から移行するユーザーのための移行パスについて説明します。

暗号化の詳細については、OWASP 暗号化ストレージチートシート を参照することをお勧めします。

§メッセージ認証

Play は `Crypto.sign` メソッドを使用して、セッション Cookie のメッセージ認証を提供します。`Crypto.sign` を Cookie の署名以外の目的で使用すべきではない理由はいくつかあります。MAC アルゴリズムの独立性、追加機能、およびパスワードハッシュアルゴリズムとしての HMAC の誤用です。

§MAC アルゴリズムの独立性

Play は現在、セッション Cookie の署名と検証に HMAC-SHA1 を使用しています。HMAC は、秘密鍵(アプリケーションシークレット として play.crypto.secret で定義)とメッセージダイジェスト関数(この場合は SHA-1)を使用して、データが改ざんされていないことを認証する暗号化関数です。SHA-1 は最近いくつかの攻撃を受けていますがメッセージの真正性のために HMAC と共に使用する場合、依然として安全です。

Play は、必要に応じて異なる HMAC 関数に移行できる柔軟性を備えている必要があるため、パブリック API の一部であってはなりません。

§潜在的な新機能

Play は現在セッション Cookie に署名していますが、セッション Cookie にセッションタイムアウトまたは有効期限を追加していません。これは、適切な機会があれば、アクティブな攻撃者がセッション Cookie を別の Cookie に置き換える可能性があることを意味します。

§パスワードハッシュとしての誤用

`Crypto.sign` やあらゆる種類の HMAC は、パスワードハッシュ用に設計されていないため、使用しないでください。MAC は高速で安価であるように設計されているのに対し、パスワードハッシュは低速で高価である必要があります。scrypt、bcrypt、または PBKDF2 を参照してください。特に jBCrypt は、Java の bcrypt 実装としてよく知られています。

§対称暗号化

Crypto には、対称暗号化のための 2 つのメソッド `Crypto.encryptAES` と `Crypto.decryptAES` が含まれています。これらのメソッドは Play の内部では使用されていませんが、大きな 開発者 の努力 これらのメソッドのレビューに費やされています。これらのメソッドは非推奨になり、将来のバージョンでは削除される可能性があります。

警告で示唆されているように、これらのメソッドは一般的に「安全」ではありません。これらのメソッドでは安全ではない一般的な操作モードがいくつかあります。以下に、`Crypto.encryptAES` を使用したいくつかの暗号化の問題について簡単に説明します。

繰り返しになりますが、`Crypto.encryptAES` は Play では直接使用されないため、これは Play 自体に対するセキュリティの脆弱性ではありません。

§認証なしのストリーム暗号の使用

`Crypto.encryptAES` は、デフォルトで AES-CTR を使用しています。これは暗号化を提供する AES のモードですが、認証は提供しません。これは、アクティブな攻撃者が暗号化されたテキストの内容を別のものと交換できることを意味します。「可変性」として知られるこの特性は、特定の条件下でプレーンテキストを復元し、メッセージを変更できることを意味します。これを軽減するために使用される 2 つの構成があります。暗号化されたテキストに署名する(「Encrypt Then MAC」として知られる)か、AES-GCM などの認証付き暗号化を使用できます。

Play は `Crypto.encryptAES` を使用してセッション Cookie の内容を暗号化します(MAC が適用されています)。Play は「Encrypt Then MAC」を使用するため、攻撃に対して脆弱ではありません。ただし、MAC なしで対称暗号化を使用しているユーザーは、潜在的に脆弱になる可能性があります。

ユーザーは、独自の Encrypt-Then-MAC 構成を実装しないことをお勧めします。代わりに、ここでは認証付き暗号化が適切なソリューションです。これにより、データの認証と暗号化が同時に実行されます。詳細については、移行セクションを参照してください。

§鍵分離原則の違反

HMAC を使用した AES は安全な構成と見なされますが、Play で秘密鍵を暗号化に使用する方法には問題があります。「鍵分離原則」では、1 つの目的には 1 つの鍵のみを使用する必要があります。この場合、play.crypto.secret は署名だけでなく、`Crypto.encryptAES` での暗号化にも使用されます。

`Crypto.encryptAES` を使用しているお客様の場合、ここで鍵の使用が混在することによる、差し迫ったセキュリティの脆弱性はありません。

「HMAC 対 AES では、そのような干渉は知られていません。暗号学者たちの一般的な見解は、AES と SHA-1(または SHA-256)は「十分に異なる」ため、AES と HMAC/SHA-1 に同じ鍵を使用しても実際的な問題は発生しないとされています。」– https://crypto.stackexchange.com/a/8086

アプリケーションが大きくなると、鍵分離原則は別の方法でも違反される可能性があります。`Crypto.encryptAES` が複数の目的で使用される場合、個別の鍵を使用することもお勧めします。

§モードのグローバル構成

前述のように、AES は様々な動作モードで使用できます。異なるモードを使用するには、異なる追加のセキュリティ対策が必要になる場合があります。

ただし、Play では、play.crypto.aes.transformation 設定オプションを設定することで、動作モードをグローバルに構成できます。つまり、`Crypto.encryptAES` を使用するすべてのライブラリを含む、アプリケーション全体に影響を与えます。その結果、オプションを変更することでアプリケーション全体にどのような影響を与えるかを正確に把握することは困難です。

§移行

Crypto 機能からの移行パスはいくつかあります。優先順位の高い順に、Kalium、Tink、または純粋な JCA です。

§Kalium

本番環境でバイナリを制御でき、NIST 承認アルゴリズムに対する外部要件がない場合:Kaliumlibsodium ライブラリのラッパー)を使用します。

`Crypto.sign` の MAC 置換が必要な場合は、HMAC-SHA512/256 を実装する `org.abstractj.kalium.keys.AuthenticationKey` を使用します。

`Crypto.encryptAES` の対称暗号化置換が必要な場合は、秘密鍵認証付き暗号化を実装する `org.abstractj.kalium.crypto.SecretBox` を使用します。

Kalium は、libsodium バイナリをインストールする必要があることに注意してください。できれば、検証済みのソースからインストールすることをお勧めします。

§Tink

純粋な Java ソリューションを探している場合、または NIST 承認アルゴリズムに依存している場合は、Tink は JCA 上に高レベルの暗号化ライブラリを提供します。Tink は libsodium/Kalium と同じレベルのサポートを持っていないため、Kalium が優先されます。

`Crypto.sign` の MAC 置換が必要な場合は、`com.google.crypto.tink.mac.MacKeyTemplates` を使用します。

`Crypto.encryptAES` の対称暗号化置換が必要な場合は、`com.google.crypto.tink.aead.AeadKeyTemplates` を使用します。

§JCA

Kalium と Tink はどちらも、Crypto とは異なる暗号化プリミティブを使用します。基盤となるアルゴリズムを変更せずに Crypto 機能から移行するユーザーにとって、最良のオプションはおそらく Crypto ライブラリからユーザーレベルのクラスにコードを抽出することです。

§さらに読む

暗号化 API とそれに伴う複雑さによって対処されるいくつかの問題について説明する、暗号化設計に関する論文がいくつかあります。

次へ:Play 2.4


このドキュメントに誤りを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインをお読みになった後、プルリクエストを送信していただければ幸いです。ご質問やアドバイスがありましたら、コミュニティフォーラムでコミュニティとの会話を開始してください。