Always Encrypted

Always Encryptedで暗号化されたカラムを復号化して表示してみた

Always Encryptedで暗号化したカラムは、Always Encryptedにより暗号化されたカラムを復号化できる設定を追加すると共に、Azure Key Vaultに対する認証を行うための設定を追加することで、復号化した値を取得することができる。

今回は、Always Encryptedで暗号化したカラムを復号化し表示してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事に従って、dbo.USER_PASSテーブルのカラム「pass_encrypted」を暗号化していること。

SQL DatabaseのカラムをSSMSを使ってAlways Encryptedで暗号化してみたAlways Encryptedを利用すると、SQL DatabaseやSQL Serverのデータベースに格納された、クレジットカード...

また、Azure Portal上に、以下の記事に従ってKey Vaultとサービスプリンシパルを作成済であること。

Azure Key Vaultを作成しKey Vaultのシークレットを取得してみた(ソースコード以外編)Azure Key Vaultを利用すると、パスワード等の機密情報へのアクセスをAzure Portal上のみに制限することができる。今...

なお、サービスプリンシパルの、Key Vaultのアクセスポリシーが以下のようになっていること。
前提条件_1

前提条件_2

さらに、下記記事の実装が完了していること。

Azure App ServiceからAzure FunctionsにPost送信してみた(ソースコード編)今回も引き続き、Azure App ServiceからPost通信によってAzure Functionsを呼び出す処理の実装について述べ...



作成したサンプルプログラム(App Service側)の内容

作成したサンプルプログラム(App Service側)の構成は以下の通り。
サンプルプログラムの構成(AppService)
なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。

コントローラクラスの内容は以下の通りで、後述のgetUserPass関数を呼び出すように修正している。

また、先ほどのgetUserPass関数を呼び出した結果に関する、dbo.USER_PASSテーブルからの取得結果をクラスの内容は以下の通り。

さらに、メイン画面の内容は以下の通りで、「getUserPassの値を取得」ボタン押下により、コントローラクラスの「getUserPass」メソッドを呼び出すようにしている。

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/azure/tree/master/always-encrypted-decrypt/demoAzureApp



作成したサンプルプログラム(Azure Functions側)の内容

作成したサンプルプログラム(Azure Functions側)の構成は以下の通り。
サンプルプログラムの構成(AzureFunctions)
なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。

<2021年4月13日 追記>
spring-cloud-function-dependenciesのバージョンは、2021年3月16日にリリースしたバージョン3.1.2を利用すると、1つのAzure Functions内に複数のファンクションを含む場合の不具合が解消できている。


その場合、Handlerクラスの継承するクラスを「AzureSpringBootRequestHandler」クラスから「FunctionInvoker」クラスに変更する。


spring-cloud-function-dependenciesの3.1.2を利用した実装サンプルは、以下の記事を参照のこと。

spring-cloud-function-dependenciesのバージョンを最新(3.1.2)にしてみたこれまでこのブログで取り上げてきたAzure Functionsのサンプルプログラムでは、spring-cloud-function-d...

pom.xmlの追加内容は以下の通りで、Microsoft SQL Server 用 JDBC Driver(mssql-jdbc)のバージョンを「8.4.1.jre8」に変更し、必要なライブラリを追加している。

なお、Microsoft SQL Server 用 JDBC Driver(mssql-jdbc)に依存するライブラリについては、以下のサイトを参照のこと。
https://docs.microsoft.com/ja-jp/sql/connect/jdbc/feature-dependencies-of-microsoft-jdbc-driver-for-sql-server?view=sql-server-ver15

application.propertiesの内容は以下の通りで、DBのURLに、Always Encryptedで暗号化されたカラムの復号化を可能にする「columnEncryptionSetting=Enabled」という設定を追加すると共に、サービスプリンシパルを利用してKey Vaultにアクセスするための設定を追加している。

なお、上記設定のkeyVaultClientId、keyVaultClientKeyには、以下のサービスプリンシパル作成時のコマンド実行時に出力されたappId、passwordの値を指定している。
サービスプリンシパルの作成

また、Azure Functionsのメインクラスは以下の通りで、オブジェクト生成後にKey Vaultの認証の接続設定を登録する処理を追加すると共に、後述のサービスクラスを呼び出しを追加している。

さらに、UserPassテーブルにアクセスするエンティティクラス・Mapperクラス・Mapper XMLの内容は以下の通りで、Always Encryptedを利用しない場合と同じ内容になっている。

また、UserPassテーブルにアクセスするサービスクラスの内容は、以下の通り。

ハンドラークラスの内容は以下の通りで、Azure App Serviceのコントローラクラスから呼ばれるgetUserPass関数である。

さらに、Azure FunctionsのメインクラスのgetUserPassメソッドの引数・戻り値は以下のクラスで定義している。

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/azure/tree/master/always-encrypted-decrypt/demoAzureFunc



サンプルプログラムの実行結果

サンプルプログラムの実行結果は、以下の通り。

1) まずは、ローカル環境で、Always Encryptedによる暗号化を行わなかった場合の実行結果は、以下の通り。

App Service側のapplication.propertiesは以下の通り。
サンプルプログラムの実行結果_1_1

Azure Functions側のapplication.propertiesは以下の通り。
サンプルプログラムの実行結果_1_2

上記の状態で、ローカル環境でdemoAzureFuncアプリを「mvn azure-functions:run」コマンドで起動した後で、Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスし、「getUserPassの値を取得」ボタンを押下した実行結果は、以下の通り。
サンプルプログラムの実行結果_1_3

サンプルプログラムの実行結果_1_4

上記結果を確認すると、下記データがそのまま表示されることが確認できる。
サンプルプログラムの実行結果_1_5

2) 次に、ローカル環境で、Always Encryptedによる暗号化を行った場合の実行結果は、以下の通り。

App Service側のapplication.propertiesは以下の通り。
サンプルプログラムの実行結果_2_1

Azure Functions側のapplication.propertiesは以下の通り。
サンプルプログラムの実行結果_2_2

上記の状態で、ローカル環境でdemoAzureFuncアプリを「mvn azure-functions:run」コマンドで起動した後で、Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスし、「getUserPassの値を取得」ボタンを押下した実行結果は、以下の通り。
サンプルプログラムの実行結果_2_3

サンプルプログラムの実行結果_2_4

上記結果を確認すると、下記データが復号化され表示されることが確認できる。
サンプルプログラムの実行結果_2_5

3) さらに、Azure環境で、Always Encryptedによる暗号化を行った場合の実行結果は、以下の通り。

App Service側のapplication.propertiesは以下の通り。
サンプルプログラムの実行結果_3_1

Azure Functions側のapplication.propertiesは以下の通り。
サンプルプログラムの実行結果_3_2

上記状態で、「mvn azure-functions:deploy」コマンドによって、Azure Functions上にサンプルプログラムをデプロイする。
サンプルプログラムの実行結果_3_3

なお、Azure Functionsにデプロイする過程は、以下の記事の「Azure FunctionsへのSpring Bootを利用したJavaアプリケーションのデプロイ」を参照のこと。

Azure Functions上でSpring Bootを利用したJavaアプリケーションを作成してみた前回は、Azure Potal上でAzure Functionsを作成してみたが、今回は、前回作成したAzure FunctionsにS...

また、 「mvn azure-webapp:deploy」コマンドによって、Azure App Service上にサンプルプログラムをデプロイする。
サンプルプログラムの実行結果_3_4

なお、Azure App Serviceにデプロイする過程は、以下の記事の「App ServiceへのSpring Bootを利用したJavaアプリケーションのデプロイ」を参照のこと。

Azure App Service上でSpring Bootを利用したJavaアプリケーションを作成してみた前回は、Azure Potal上でApp Serviceを作成してみたが、今回は、前回作成したApp ServiceにSpring Bo...

その後、Azure App ServiceのURL「https://azureappdemoservice.azurewebsites.net/」とアクセスした場合の実行結果は、以下の通り。
サンプルプログラムの実行結果_3_5

なお、上記URLは、下記Azure App ServiceのURLから確認できる。
サンプルプログラムの実行結果_3_6

その後、「getUserPassの値を取得」ボタンを押下すると、以下の画面が表示され、Always Encryptedで暗号化したカラムが復号化し表示されることが確認できる。
サンプルプログラムの実行結果_3_7

サンプルプログラムの実行結果_3_8

要点まとめ

  • Always Encryptedで暗号化したカラムを復号化するには、JDBC接続文字列に「columnEncryptionSetting=Enabled」を追加すると共に、サービスプリンシパルを経由してAzure Key Vaultに対する認証を行うための設定を追加すればよい。