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で暗号化されたカラムの復号化を可能にする設定を追加すると共に、サービスプリンシパルを利用して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に対する認証を行うための設定を追加すればよい。