Azure SQL DatabaseでAlways Encryptedを使って暗号化してみた

##きっかけ
先日AZ-500（Azure Security Technologies）の研修を受講してきました。
研修ではAzureのセキュリティついて様々なサービスや機能を一通り知ることができましたが、データベース周りの部分は私自身実践経験がなく、研修でも演習の時間が十分になかったため今回の検証対象として取り上げてみました。

##Always Encryptedとは
SQLデータベースを暗号化する機能。　※SQL Server 2016 導入
SQLクライアント側にて暗号化/復号化を実施。
※暗号化すると、SSMSからは参照しかできなくなる。

暗号化範囲：列(カラム)単位
暗号化テクノロジー：AES256(CEK) , RSA(CMK)
暗号化キーの管理：ユーザー (Azure Key Vault)
※暗号化対象となるSQLと同一リージョンであること

●サポート対象
Azure SQL Database、SQL Server(2016以降)

●仕組み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/36774ef2-f1aa-6a98-82be-2d689a9117a3.png)

[暗号化]
[SSMS(SQL Server Management Studio)]は[CMK]を作成し[UserID]を使い[KeyVault]に格納。[CMK]より[CEK]を生成し暗号化を実施。[CEK]はDBに格納。

[復号化]
・[SSMS]は[UserID]を使い[KeyVault]から[CMK]、[CEK]を取得し復号化する。
・[SQL Client]は[AzureAD App]を使い[KeyVault]から[CMK]、[CEK]を取得し復号化する。

●今回の検証内容
今回は、Always Encryptedを使ってAzure SQL Databaseのデータを暗号化する。マスターキー(CMK)はAzure Key Vaultに格納する。という部分を以下の手順で検証して確認しました。
※Azure SQL Databaseの論理サーバーとデータベースの作成、ファイアウォール規則の構成等の手順は基本的に省略します。

##検証手順

###Azure SQL Databaseの作成
今回の検証ではサンプルデータを使用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/bf6614bc-43b6-6e17-259d-b61468da64cd.png)

###Azure Key Vaultコンテナーの作成
作成画面で現在ログインしているユーザーの"キーのアクセス許可"で赤枠の部分を追加で選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/6fdf4b82-dd92-f2a2-b6b2-b968b2008469.png)

###Always Encryptedの構成と暗号化の確認
SSMSでSQLサーバーに接続する。
※SQLサーバーに接続するクライアントのIPをSQLサーバーのファイアウォール規則に追加する必要あり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/15b9a3ed-d8c9-13a0-4f3b-e25c7f9e8cd6.png)


暗号化前の状態を確認。
今回は赤枠の[PasswordHash] 列を暗号化していく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/9e91fc2e-a752-c076-4a76-7a5395da7db8.png)


暗号化したいデータベースのテーブルを右クリック→[列の暗号化] を選択。
⇒ Always Encrypted ウィザードが開始。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/200e9e5f-5467-3e75-942f-ce4a5ac707ac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/3c11f295-3ba8-9ec8-2a6a-67002c916105.png)
テーブル内の暗号化する列を選択。
[PasswordHash] 列にチェックをつけて、暗号化の種類を [決定論的] に設定。
※暗号化方式には決定論的とランダム化の２種類ある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/50d6def1-0c9b-fab3-2578-9d70dd71a1f1.png)
マスターキーの構成画面で [キーストア プロバイダーを選択] を [Azure Key Vault] に設定し、[サインイン] をクリック。
Azure ポータルでログインしたアカウント、パスワードでサインイン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/56c9f46c-a3b2-c603-07a8-05585a7a4684.png)
マスターキーの構成画面で [Azure Key Vault を選択] を前手順で作成したキーコンテナーに設定し、 [次へ] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/bf21d3af-6a2c-64af-dc5d-3b52828ee08a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/faf81a76-13dc-de89-e941-56619fcaefaa.png)
実行設定画面で [続行して今すぐ実行] が選択されていることを確認し、[次へ] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/08dfb934-17b8-8978-b675-85d66e205a97.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/aa8ba40a-bae6-a3f9-b303-bc49da43a47d.png)

赤枠の[PasswordHash] 列が暗号化されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/cc382ad9-0111-504d-2690-3b63b1538ec5.png)

###復号化して表示する
Optionsをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/65d8800b-4387-a43a-6b30-79e061e977be.png)
[データベース エンジンへの接続] で [追加の接続パラメーター] タブを選択して 「Column Encryption Setting=enabled」 と入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/60eea1ec-0d4c-3079-57b4-e614397e7707.png)
[PasswordHash] 列が復号化した状態で表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/40cc325a-66d3-6173-3a52-eda39a6464ae.png)

###(参考)鍵の格納場所を確認
マスターキー[CMK_Auto1]、暗号化キー[CEK_Auto1]が作成されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/e01b6a57-d841-ce11-c17a-11dbb804f7ec.png)
暗号化キー[CEK_Auto1]はデータベース内に保管
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/9e32cac2-9568-5dae-a409-9f8d5b1fbe6e.png)
マスターキー[CMK_Auto1]はAzure Key Vaultに格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641192/0cfad93e-a779-e821-49e5-8f4061af0483.png)

##最後に
Always Encryptedを使用する最大のメリットは"通信経路も含めて常に暗号化した状態でデータを操作できること"です。
Azure SQL Databaseで作成されるユーザーデータベースは既定で透過的データ暗号化（TDE）が構成され暗号化されますが、クライアントアプリケーションからデータを読み込むとき、バックグラウンドプロセスで復号化されるため、アプリケーションが読むデータは平文となります。
そこでAlways Encryptedを使用すると、暗号化/復号化をクライアント側で実施するのでアプリケーションが読むデータも暗号化された状態を保つことができます。（＝通信経路上も暗号化されたまま）

今回の検証はあくまでAlways Encryptedの暗号化機能を確認するだけの簡易的なものでしたが、実際のシステムではアプリケーションからデータベースの暗号化したデータにアクセスし、復号化するといった構成が求められるはずです。
その際はアプリに対して暗号化キーの保管場所であるKeyVaultへのアクセス権限を付与したり、アプリからデータベースへの接続方法などを検討する必要があります

また、データベースのセキュリティについてはデータの暗号化だけでなく認証/アクセス制御といった部分も重要になってきます。
前述の透過的なデータ暗号化（TDE）や行レベルのセキュリティなどAlways Encrypted以外のデータ保護方法を検討する必要もあります。
システム要件を満たすには、これら様々な要素を組み合わせていくことが求められると思いますので、今後の検証ではアプリとの連携部分などもやっていきたいです。