OWASP ASVS 4.0 V6 から保存時の暗号化について考える。

# OWASP ASVSとは
Application Security Verification Standard 4.0 - アプリケーションセキュリティ検証基準です。検証つまりテストに関する基準なのですが、WebアプリケーションおよびWebサービスを設計、開発およびテストする時のセキュリティ要件についてまとめられています。

> 本ページでは、下記を参考にさせていただいております。
> OWASP ASVS 4.0：https://owasp.org/www-project-application-security-verification-standard/
> 日本語訳参考：https://qiita.com/prt445/items/42856a66666aae65a16e


# V6: Stored Cryptography Verification Requirements
V6は、保存時の暗号化に関する検証要件です。

ポイントは以下の３点です。

- すべての暗号化処理は、安全な方法で失敗し、エラーは正しく処理されます。
- 適切な乱数発生器が使用されます。
- 鍵へのアクセスは安全に管理されます。

## V6.1 Data Classification
データを正しく分類にするために、privacy impact assessmentを実施するよう記載されています。
privacy impact assessmentとは、[wikipedia](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%A9%E3%82%A4%E3%83%90%E3%82%B7%E3%83%BC%E5%BD%B1%E9%9F%BF%E8%A9%95%E4%BE%A1)にも記載されてますが、プライバシー影響評価というものです。

> 
プライバシー影響評価（プライバシーえいきょうひょうか、英語: Privacy Impact Assessment、略称：PIA（ピーアイエー））とは、個人情報の収集を伴う情報システムの企画、構築、改修にあたり、情報提供者のプライバシーへの影響を「事前」に評価し、情報システムの構築・運用を適正に行うことを促す一連のプロセスをいう。

実際の要件は下表です。

ここでL1,L2,L3は、ASVSレベルと呼ばれるもので、レベルが上がるにつれてより詳細な要件になります。
L1：低保証アプリケーション用のレベルです。ペネトレーションテストが可能な要件になってます。
L2：機密データ、個人情報を含むアプリケーション用のレベルです。ほとんどのアプリケーションに推奨される要件になってます。
L3：最も重要なアプリケーション、高額の取引、医療情報などを扱うアプリケーション用のレベルです。

| # | Description | L1 | L2 | L3 | CWE |
| :---: | :--- | :---: | :---:| :---: | :---: |
| **6.1.1** | Verify that regulated private data is stored encrypted while at rest, such as personally identifiable information (PII), sensitive personal information, or data assessed likely to be subject to EU's GDPR. |  | ✓ | ✓ | 311 |
| **6.1.2** | Verify that regulated health data is stored encrypted while at rest, such as medical records, medical device details, or de-anonymized research records. |  | ✓ | ✓ | 311 |
| **6.1.3** | Verify that regulated financial data is stored encrypted while at rest, such as financial accounts, defaults or credit history, tax records, pay history, beneficiaries, or de-anonymized market or research records. |  | ✓ | ✓ | 311 |

### 6.1.1
個人を特定できる情報（PII）、機密性の高い個人情報、またはEUのGDPRの対象となる可能性が高いと判断されたデータなど、規制対象のプライバシーデータが暗号化されて保管されていることを確認します。

具体的にどういった対象のデータを暗号化すればいいでしょうか？そもそも暗号化して保存するのは、そのデータが万が一、流出してしまった際に、暗号化しておけば、中身を見られる心配が少なくなるからです。漏えいしてはいけない機密性の高いデータが対象になります。

次に暗号化はどのレベルで実施するかです。

- アプリケーションレベル
- データベースレベル
- ファイルシステムレベル（BitLockerなど）
- ハードウェアレベル（HDDやSSDの暗号化）

例えば、ハードウェアレベルで暗号化した場合、HDDを持ち出すような物理的な攻撃には強いですが、リモートでアクセスするような攻撃の場合、復号したデータが見えるので、意味をなさないかもしれません。"誰から"守かによって変わってきます。

さて、OWASP ASVSは検証基準なので、検証しなければなりません。"暗号化されて保管されていることを確認"するには、どうすればいいでしょうか？ペネトレーションテストのようなブラックボックステストでは、確認できません。実際にデータを見る必要があります。検証する人が、データを見る権限がない場合は、開発者やデータを閲覧できる人へのインタビューが必要になります。

### 6.1.2
医療記録、医療機器の詳細、匿名化されていない研究記録など、規制対象の医療データが暗号化されて保存されていることを確認します。

### 6.1.3
金融口座、債務不履行やクレジットの履歴、税務記録、支払い履歴、信託受益者、匿名化されていない市場や調査記録など、規制対象の財務データが暗号化されて保管されていることを確認します。

6.1.2も6.1.3も同様の要件です。

## V6.2 Algorithms
過去に安全であったアルゴリズムや鍵長が最近になって、データを保護するのに安全ではないことがわかることがあります。そのため、アルゴリズムを変更できるようにすべきです。

V6.2の要件の詳細は下表です。


| # | Description | L1 | L2 | L3 | CWE |
| :---: | :--- | :---: | :---:| :---: | :---: |
| **6.2.1** | Verify that all cryptographic modules fail securely, and errors are handled in a way that does not enable Padding Oracle attacks. | ✓ | ✓ | ✓ | 310 |
| **6.2.2** | Verify that industry proven or government approved cryptographic algorithms, modes, and libraries are used, instead of custom coded cryptography. ([C8](https://www.owasp.org/index.php/OWASP_Proactive_Controls#tab=Formal_Numbering)) | | ✓ | ✓ | 327 |
| **6.2.3** | Verify that encryption initialization vector, cipher configuration, and block modes are configured securely using the latest advice. |  | ✓ | ✓ | 326 |
| **6.2.4** | Verify that random number, encryption or hashing algorithms, key lengths, rounds, ciphers or modes, can be reconfigured, upgraded, or swapped at any time, to protect against cryptographic breaks. ([C8](https://www.owasp.org/index.php/OWASP_Proactive_Controls#tab=Formal_Numbering)) | | ✓ | ✓ | 326 |
| **6.2.5** | Verify that known insecure block modes (i.e. ECB, etc.), padding modes (i.e. PKCS#1 v1.5, etc.), ciphers with small block sizes (i.e. Triple-DES, Blowfish, etc.), and weak hashing algorithms (i.e. MD5, SHA1, etc.) are not used unless required for backwards compatibility. | | ✓ | ✓ | 326 |
| **6.2.6** | Verify that nonces, initialization vectors, and other single use numbers must not be used more than once with a given encryption key. The method of generation must be appropriate for the algorithm being used. | | ✓ | ✓ | 326 |
| **6.2.7** | Verify that encrypted data is authenticated via signatures, authenticated cipher modes, or HMAC to ensure that ciphertext is not altered by an unauthorized party. | | | ✓ | 326 |
| **6.2.8** | Verify that all cryptographic operations are constant-time, with no 'short-circuit' operations in comparisons, calculations, or returns, to avoid leaking information. | | | ✓ | 385 |

### 6.2.1
全ての暗号化モジュールでフェイルセキュアで、Padding Oracle攻撃が有効でない方法でエラーハンドリングされることを確認します。

フェイルセキュアとは、フェイルセーフと似た考え方と思います。常に安全に失敗することです。例えば、飛行機の場合に、エンジン故障で全推力を失っても滑空して無事着陸できるようであれば、ファイルセーフと言えます。
システムであれば、例えば、`isAdmin()`という管理者かどうかを判断する関数を作った時に、処理中で例外が発生した際に、常に`false`を返すようにするとファイルセーフと言えるかもしれません。

Padding Oracle攻撃とは、鍵を持っていないにも関わらず暗号文を解読できてしまう攻撃方法です。適当なデータ列を暗号文として送り、パディングが不正である場合に発生する特殊なエラー、または処理されないという事実を利用し、そのデータ列が暗号文として適切かどうかを調べます。防ぐためには、復号のエラーハンドリングの際に、復号の成否のみを返すようにします。

つまり、余計な情報を与えず、安全に失敗することを確認します。例えば、ユーザの個人情報を暗号化しており、そのユーザがマイページで自分の情報を見るときに復号に失敗したのであれば、ユーザにはシステムエラーが発生したことだけを表示して、ログなどで失敗理由や箇所を残しておけば良いと思います。

### 6.2.2
カスタムコーディングされた暗号化方式の代わりに、業界で実績のある、または政府が承認した暗号化アルゴリズム、モード、およびライブラリが使用されていることを確認します。

暗号化方式は、特段の指定がない限り自身で実装することはないと思います。承認されたものを使いましょう。
”government approved”ですが、日本であれば、[CRYPTREC](https://www.cryptrec.go.jp/)を参考にしてください。[OWASP Cheat Sheet: Cryptographic Storage](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)も参考になると思います。

２つを参考にすると、共通鍵暗号であれば、AESの256ビットでモードはCCMかGCMを使うといいと思います。

### 6.2.3
最新の勧告を使用して、暗号化初期化ベクトル、暗号設定およびブロックモードが安全に設定されていることを確認します。

例えば、[OWASP Cheat Sheet: Cryptographic Storage](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)が、latest adviceとするのであれば、暗号化鍵や初期化ベクトルを生成する際には、暗号学的擬似乱数生成器（CSPRNG）を使います。
また、ブロックモードには、CCMかGCMを使うようアドバイスされています。

### 6.2.4
暗号が破られた場合に備えて、乱数、暗号化またはハッシュアルゴリズム、鍵の長さ、ラウンド、暗号またはモードをいつでも再設定、置き換えられることを確認する。

暗号は破られる可能性があります。現に、CRYPTRECの更新履歴を見ると毎年更新されています。今使っている暗号アルゴリズムやモードが数年すると危険なものになっている可能性があるので、暗号アルゴリズムやモードを変更できるようにしておく必要があります。

では、どうやって変更できるようになっているかを確認するのでしょうか？
開発者にインタビューするのが良いでしょう。そして、できれば実際に変更してみるといいと思います。暗号アルゴリズムを変更するのであれば、保存された暗号文を全て、暗号化しなおすかもしれません。実際に、そのオペレーションも含めて検証すると良いと思います。

### 6.2.5
既知の安全でないブロックモード（ECBなど）、パディングモード（PKCS#1 v1.5など）、ブロックサイズが小さい暗号（Triple-DES、Blowfishなど）、および弱いハッシュアルゴリズム（MD5、SHA1など）が、下位互換性のために必要とされない限り使用されていないことを確認します。

どれが使ってはいけないのかの判断は、難しいので、[CRYPTREC](https://www.cryptrec.go.jp/)や[OWASP Cheat Sheet: Cryptographic Storage](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)を参考にするといいと思います。

### 6.2.6
nonces、initialization vectors(IV)、その他1回限りの数字が特定の暗号鍵で複数回使われないことを確認します。生成方法は、使用しているアルゴリズムで適切なものを使います。

initialization vectors(IV)：初期化ベクトルは、同じ平文が同じ暗号文にならないようにするために使用するデータのこと。
nonces：ノンスは、暗号通信で用いられる、使い捨てのランダムな値のこと。たいてい、認証の過程で使われ、リプレイ攻撃を行えないようにする働きを担っている。（毎回異なる値を発行して、リプレイ攻撃を防ぐ）

この要件を確認するために、保存されたIVやnoncesを確認するのがいいと思います。もしくは開発者にインタビューするのがいいかもしれません。

### 6.2.7
暗号化されたデータが、権限のない者によって変更されていないことを確認するために、署名や認証された暗号化モードまたはHMACによって認証されていることを確認する。

CCMやGCMモードを使うと完全性がチェックできるので、この要件を満たすことができます。

確認するには、実際に暗号化されたデータを改ざんしてみるといいかもしれません。同じ条件で暗号化した別の平文のデータに改ざんして、復号が失敗することを確認できれば良いと思います。

### 6.2.8
情報の漏洩を防ぐために、すべての暗号化処理が、比較や計算またはリターンの際に「short-circuit」処理がない一定時間であることを確認します。

'short-circuit' operationsは、short circuit evalutionと同義で使われていると仮定すると最小評価を意味します。プログラミング言語において、論理演算子における左辺（第一引数）と右辺（第二引数）の式の評価法のひとつです。

例えば、`if (A && B)`の場合、Aが`false`なら、Bを評価するまでもなく、式全体が`false`。`if (A || B)`の場合、Aが`true`なら、Bは評価するまでもなく、式全体が`true`。このように左辺（第一引数）を評価した段階で式全体の値が定まる場合、右辺（第二引数）を評価しない、というのがshort circuit evalutionです。

このような評価がないように、成功時も失敗時も一定時間で終わることを確認します。

## V6.3 Random Values

| # | Description | L1 | L2 | L3 | CWE |
| :---: | :--- | :---: | :---:| :---: | :---: |
| **6.3.1** | Verify that all random numbers, random file names, random GUIDs, and random strings are generated using the cryptographic module's approved cryptographically secure random number generator when these random values are intended to be not guessable by an attacker. |  | ✓ | ✓ | 338 |
| **6.3.2** | Verify that random GUIDs are created using the GUID v4 algorithm, and a cryptographically-secure pseudo-random number generator (CSPRNG). GUIDs created using other pseudo-random number generators may be predictable. |  | ✓ | ✓ | 338 |
| **6.3.3** | Verify that random numbers are created with proper entropy even when the application is under heavy load, or that the application degrades gracefully in such circumstances. |  |  | ✓ | 338 |

### 6.3.1
すべての乱数、乱数ファイル名、乱数GUIDおよび乱数文字列は、暗号モジュールの承認されたCSRPNGを使って生成される。これらの乱数値が攻撃者に推測されないようにする時には。

CSRPNG：cryptographically secure presedo-random number generatorは、安全な擬似乱数生成器です。推測されないような乱数を作りたい場合は、これらを使います。

PHP7なら、`random_bytes()`, `random_int()`です。（rand(), mt_rand(), array_rand(), uniqid()）を使いません。

ここでも[OWASP Cheat Sheet: Cryptographic Storage](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)を参考にするのが良いと思います。

### 6.3.2
ランダムなGUID(UUID)は、GUID v4 algorithmとCSPRNGを使って作成されることを確認します。

PHP7の場合には、上記と同じ関数を使ってランダムな文字を生成します。

GUID v4 algorithmについて知りたい場合は、Wikipediaを参考にしていただくと良いと思います。
https://ja.wikipedia.org/wiki/UUID

16進数表記だと`RRRRRRRR-RRRR-4RRR-rRRR-RRRRRRRRRRRR`となり、rにバリアントと呼ばれ、バージョン4バリアント1（ほとんどのUUID）では、上位2ビットが`10`、つまり`1000`,`1001`,`1010`,`1011`で１６進数では、8,9,A,Bのいずれかがランダムで入る。残りのRには、ランダムな`0-F`までの文字が入ります。

### 6.3.3
アプリケーションに大きな負荷がかかっている場合でも乱数が適切なエントロピーで作成されていること、またはそのような状況でアプリケーションが適切にデグレードすることを確認します。

適切なエントロピーですが、エントロピーはどれくらいランダムに発行されているかを表した数字のことです。数字が大きい方が、ランダムに生成されていると言えランダム性が高いと言えます。
Burp Suiteの中に入っているBurp Sequencerを使うと計測できます。
[Burp Sequencer入門](https://burp-resources-ja.webappsec.jp/Documentation/burp/documentation/desktop/tools/sequencer/getting-started.html)

## V6.4 Secret Management
この章の項目は、ペネトレーションテストでは、検出できませんが、L1レベルの項目です。

| # | Description | L1 | L2 | L3 | CWE |
| :---: | :--- | :---: | :---:| :---: | :---: |
| **6.4.1** | Verify that a secrets management solution such as a key vault is used to securely create, store, control access to and destroy secrets. ([C8](https://www.owasp.org/index.php/OWASP_Proactive_Controls#tab=Formal_Numbering)) | | ✓ | ✓ | 798 |
| **6.4.2** | Verify that key material is not exposed to the application but instead uses an isolated security module like a vault for cryptographic operations. ([C8](https://www.owasp.org/index.php/OWASP_Proactive_Controls#tab=Formal_Numbering)) | | ✓ | ✓ | 320 |

### V6.4.1
key vault（鍵保管庫）のような、秘密情報管理ソリューションが安全な鍵の生成、保管、アクセスコントロール及び破壊に使われていることを確認します。

key vaultとは、AWSならAWS Key Management Service (KMS)、AzureならKey Vaultです。他にもありますが、AWS KMSが使いやすいです。
[暗号化って結局どれを選べば良いの？OWASP Cryptographic Storage Cheat Sheetまとめ](https://qiita.com/koujimatsuda11/items/0105d75ca626b32b9d44#amazon-kms%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%AE%9F%E8%A3%85)という記事でAWS KMSの使い方を紹介しています。


### 6.4.2
key materialが、アプリケーションにベタ書きされていないことを確認します。代わりに、暗号化操作用のvault(保管庫)などの隔離されたセキュリティモジュールを使用していることを確認します。

暗号化するための鍵の管理の話です。アプリケーションにベタ書きするのではなく、権限管理されたコンフィグレーションファイルやAWS KMSのようなサービスを使うようにしましょう。

# まとめ
OWASP ASVS V6は、暗号化に関する検査標準です。そもそも暗号化しなければならないようなデータを扱わないことが一番なのですが、そういったデータを扱う場合は、以下に注意しましょう。

- すべての暗号化処理は、安全な方法で失敗し、エラーは正しく処理されます。
- 適切な乱数発生器が使用されます。
- 鍵へのアクセスは安全に管理されます。

# 参考

* [CRYPTREC](https://www.cryptrec.go.jp/)を参考にしてください。[OWASP Cheat Sheet: Cryptographic Storage]
* [OWASP Cheat Sheet: Cryptographic Storage](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)
* [FIPS 140-2](https://csrc.nist.gov/publications/detail/fips/140/2/final)