Crypto移行ガイド / Play2.5【翻訳】

https://www.playframework.com/documentation/2.6.x/CryptoMigration25 を google翻訳した

# Crypto移行ガイド

Play 1.xから、Playにはいくつかの暗号操作を提供するCryptoオブジェクトが付属しています。これはPlayによって内部的に使用されます。Cryptoオブジェクトはドキュメントには記載されていませんが、scaladocでは「暗号化ユーティリティ」として記述されています。
これらのユーティリティは便宜的なものですが、各メソッドのドキュメントを読み、このクラスを適切に使用するための暗号化の概念を理解することが重要です。安全な暗号化は難しく、暗号の十分な理解に代りはありません。これらの方法は、すべての暗号化ニーズに適していません。
さまざまな理由から、便宜のために暗号化ユーティリティを提供することは不可能であることが判明しました。2.5.xでは、Play固有の機能が `CSRFTokenSigner` 、および `AESSigner` トレイトに 分割され 、 `Crypto` シングルトンオブジェクトは廃止されました。
このドキュメントの残りでは、Cryptoの背後にある内部機能、暗号操作の適切性（および不適当性）、およびCrypto機能を無効にするユーザーの移行パスについて説明します。
暗号化の詳細については、 [OWASP Cryptographic Storage Cheatsheet](https://www.owasp.org/index.php/Cryptographic_Storage_Cheat_Sheet) をお読みください。

## メッセージ認証

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

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

現在、Play は HMAC-SHA1 をセッションCookieの署名と確認に使用していますさ。 [HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) は 、データが秘密鍵（使用して、改ざんされていないことを認証する暗号化機能である [アプリケーションシークレット](https://www.playframework.com/documentation/2.6.x/ApplicationSecret)) （この場合は [SHA-1](https://en.wikipedia.org/wiki/SHA-1)) 関数をメッセージダイジェストと共に `play.crypto.secret` として定義される）。SHA-1は 最近 [いくつかの攻撃を受けました](https://sites.google.com/site/itstheshappening/) が 、 [メッセージの信頼性](https://killring.org/2014/01/05/how-broken-is-sha-1/) のためにHMACとともに使用されると安全です。
Play では、 [必要に応じて](http://valerieaurora.org/hash.html) 異なるHMAC関数に移動できる柔軟性が必要であるため、パブリックAPIの一部であってはなりません。

### 潜在的な新機能

Playは現在、セッションCookieに署名しますが、セッションのタイムアウトまたは有効期限をセッションCookieに追加しません。これは、適切な開始点がある場合、アクティブな攻撃者がセッションCookieを別のセッションCookieに置き換えることができることを意味します。
Playは、 セッションタイムアウト機能を `Crypto.sign` に追加する可能性があります。これにより、パブリックAPIとしてマークされている場合はユーザーレベルの機能が中断されます。

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

パスワードハッシュ用に設計されていないので、 `Crypto.sign` またはあらゆる種類のHMACを使用しないでください 。MACは高速かつ安価に設計されていますが、パスワードハッシングは遅くて高価になるはずです。scrypt、bcryptの、またはPBKDF2を見てください- [jBCrypt](http://www.mindrot.org/projects/jBCrypt/) は特に Javaでbcryptの実装として知られています。

## 対称暗号化

Cryptoには、 `Crypto.encryptAES` と `Crypto.decryptAES` の 2つの対称暗号化方式が含まれています 。これらのメソッドは、 Play によって内部的に使用されていませんが、[かなりの](https://github.com/playframework/playframework/issues/4407) [開発者](https://groups.google.com/d/msg/play-framework-dev/Rlrt89Ky_Rk/j6Iq6-snDw8J) [リソースが](https://groups.google.com/forum/#!topic/play-framework/Pao8MnADAqw)このメソッドの見直しに[費やされてきました](https://ipsec.pl/play-framework/2014/session-variables-encryption-play-framework.html)。これらのメソッドは非推奨となり、将来のバージョンでは削除される可能性があります。
警告で言及されているように、これらのメソッドは一般的に「安全」ではありません。これらのメソッドを使用して安全でないいくつかの一般的な操作モードがあります。ここでは、 `Crypto.encryptAES` を使用したいくつかの暗号問題について簡単に説明します 。
繰り返しますが、 `Crypto.encryptAES` はPlayで直接使用されることはありません。したがって、これはPlay自体のセキュリティ上の脆弱性ではありません。

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

`Crypto.encryptAES` は、暗号化を提供するが認証を提供しないAESのモードであるAES-CTRを使用しています。つまり、攻撃者が暗号化されたテキストの内容を別のものに 取り替える ことができます。このプロパティは、「可用性」と呼ばれ、 特定の条件下で[平文を回復](https://news.ycombinator.com/item?id=639761)し、メッセージを変更する ことが可能であることを意味します。暗号化されたテキストが署名されている（「Encrypt Then MAC」と呼ばれる）か、AES-GCMなどの認証された暗号化のいずれかを使用することができます。
Playは `Crypto.encryptAES` を使用してセッションクッキーの内容を暗号化します（MACが適用されています）。Playは「Encrypt Then MAC」を使用するため攻撃の脆弱性はありませんが、MACなしで対称暗号化を使用しているユーザーは潜在的に脆弱です。
ユーザーは独自の Encrypt-Then-MAC 構築を実装しないことをお勧めします。代わりに、ここでの適切なソリューションは認証された暗号化です。これは同時にデータの認証と暗号化の両方を行います。詳しくは、移行のセクションを参照してください。

### 鍵分離原則の違反

HMACでAESを使用することは安全な構築と見なされますが、Playが暗号化に秘密鍵を使用する方法に問題があります。「キー分離の原理」では、1つの目的で1つのキーのみを使用してください。この場合、署名にはplay.crypto.secretが使用されるだけでなく、 `Crypto.encryptAES` での 暗号化も使用されます。
`Crypto.encryptAES` を使用している場合、キーの使用方法が混在しているため、直ちにセキュリティ上の脆弱性はありません。
「HMAC対AESでは、そのような干渉は知られていません。 暗号化技術者の一般的な感覚は、AESとHMAC / SHA-1に同じ鍵を使用することで実際的な問題がないように、AESとSHA-1（またはSHA-256）は「十分に異なる」ということです。 crypto.stackexchange.com/a/8086
アプリケーションが大きくなると、鍵の分離の原則も違反する可能性があります。`Crypto.encryptAES` を複数の目的で使用する場合 は、別々のキーを使用することもお勧めします。

### モードのグローバル設定

上記のように、AESは様々な動作モードで使用できます。別のモードを使用すると、異なるセキュリティ対策が必要になることがあります。
ただし、play.crypto.aes.transformationを設定することで、モードをグローバルにコンフィグレーションすることができます。つまり、 Crypto.encryptAES を使用するすべてのライブラリを含むアプリケーション全体に影響を与えます 。その結果、アプリケーション全体でオプションを変更した場合の影響を正確に把握することは困難です。

## 移行

暗号化機能からは、いくつかの移行パスがあります。好みの順に、それらは Kalium、Keyczar、または純粋なJCAです。

### Kalium

実稼働環境のバイナリを管理し、NISTで承認されたアルゴリズムの外部要件がない場合は、 [libsodium](https://download.libsodium.org/doc/) ライブラリのラッパーである [Kalium](https://abstractj.github.io/kalium/) を 使用 してください。
`Crypto.sign` の MAC置換が必要な場合は、 `org.abstractj.kalium.keys.AuthenticationKey` を使用してください。 - HMAC-SHA512 / 256を実装しています。
`Crypto.encryptAES` の対称暗号化を置き換えるには、 `org.abstractj.kalium.crypto.SecretBox` を使用します。これは[ 秘密鍵の認証された暗号化](https://download.libsodium.org/doc/secret-key_cryptography/authenticated_encryption.html) を実装します。
Kaliumでは、libsodiumバイナリを [インストール](https://download.libsodium.org/doc/installation/index.html) する必要があります。確認するソースからバイナリをインストールすることをお勧めします。

### Keyczar

純粋なJavaソリューションを探している場合、またはNIST認定のアルゴリズムに依存している場合、 [Keyczar](https://tersesystems.com/2015/10/05/effective-cryptography-in-the-jvm/) はJCAの上に高水準の暗号ライブラリを提供します。 Keyczarにはlibsodium / Kaliumと同じレベルのサポートがないため、Kaliumが優先されます。
`Crypto.sign` の MAC置換が必要な場合は、 `org.keyczar.Signer` を使用して ください。
`Crypto.encryptAES` の 対称暗号化の置換が必要な場合は、 `org.keyczar.Crypter` を使用します。

### JCA

KaliumとKeyczarは、Cryptoとは異なる暗号プリミティブを使用します。基盤となるアルゴリズムを変更せずにCrypto機能から移行する予定のユーザーにとっては、Cryptoライブラリからユーザーレベルのクラスにコードを抽出することをお勧めします。

## 参考文献

暗号化設計で利用可能ないくつかの論文があり、暗号化APIによって解決されるいくつかの問題とそれに関連する複雑さについて説明しています。
  * [論文からソフトウェアまでの長い旅：クリプトAPI](http://crypto.junod.info/IACR15_crypto_school_talk.pdf)
  * [Crypto APIデザインで間違っているもの](http://spar.isi.jhu.edu/~mgreen/CryptoAPIs.pdf)
  * [Real World Crypto 2015：エラーが発生しやすい暗号設計（djb）](http://bristolcrypto.blogspot.com/2015/01/real-world-crypto-2015-error-prone.html) と [スライド](http://cr.yp.to/talks/2015.01.07/slides-djb-20150107-a4.pdf)