はじめに
先日から書いているAzure SDK for Javaを使ってAzure Storage Blobにアクセスする方法の続きです。今回は、Azure Storage Blobに保存するデータのクライアント暗号化を試したいと思います。
これまでの記事はこちらを。
- Azure SDK for Javaを使ってAzure Storage Blobにアクセスする - miyohide's blog
- Azure SDK for Javaを使ってAzure Storage Blobにアクセスする(2) - miyohide's blog
Azure Storageでの暗号化
以下のドキュメントにあるように、デフォルトではAzure Storageに対してデータを保存するときに暗号化されるとのこと。これは無効化できないようです。
今回試したいのは、クライアント暗号化というもの。詳細は以下のドキュメントに記載があります。
Java SDK v12を使ったサンプルは、記事執筆時点でドキュメント内には書かれていませんでしたので、試してみることにしました。
Azure Key Vaultにおけるキーの作成と権限付与
まずはAzure Key Vaultにてキーを作成します。あまり難しいことはなく、ポータルで簡単に作成します。
作成したら、前回の記事で作成したエンタープライズアプリケーションに対してアクセス制御(IAM)とアクセスポリシーを設定します。
アクセスポリシーの権限はとりあえず暗号化操作に関するものに対して全てチェックを入れました。
Javaを使った実装
実装はAzure Storage Blobs Cryptography client library for Javaを使って行います。
azuresdkdocs.blob.core.windows.net
build.gradleに対して関連ライブラリを追記します。Azure Key Vaultでのキー用のcom.azure:azure-security-keyvault-keys
のほかcom.azure:azure-storage-blob-cryptography
を追記します。
dependencies { implementation platform('com.azure:azure-sdk-bom:1.2.0') implementation 'com.azure:azure-storage-blob' implementation 'com.azure:azure-security-keyvault-keys' implementation 'com.azure:azure-identity' implementation 'com.azure:azure-storage-blob-cryptography' implementation 'ch.qos.logback:logback-classic:1.2.11' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' }
具体的な実装方法については、Azure Storage Blobs Cryptography client library for JavaのREADMEを参考にします。まずAsyncKeyEncryptionKey
を返すメソッドを作成します。
public KeyVaultKey getKeyVaultKey(String keyName) { return (new KeyClient()).getKey(keyName); } public AsyncKeyEncryptionKey createAsyncKeyEncryptionKey(String keyName) { KeyVaultKey key = this.getKeyVaultKey(keyName); AsyncKeyEncryptionKey asyncKeyEncryptionKey = new KeyEncryptionKeyClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .buildAsyncKeyEncryptionKey(key.getId()) .block(); return asyncKeyEncryptionKey; }
これを使ってEncryptedBlobClient
を作成します。
EncryptedBlobClient encryptedBlobClient = new EncryptedBlobClientBuilder() .key(this.keyVaultHelper.createAsyncKeyEncryptionKey("Azure Key Vaultのキーの名前"), KeyWrapAlgorithm.RSA_OAEP.toString()) .credential(new DefaultAzureCredentialBuilder().build()) .endpoint("Azure Storageのエンドポイント") .containerName("コンテナ名") .blobName("Blob名") .buildEncryptedBlobClient();
key
メソッドのアルゴリズムについてJava Docには書かれていなかったので何を指定すれば分からなかったのですが、今回はKeyWrapAlgorithm.RSA_OAEP.toString()
を指定することでうまく動きました。他にもKeyWrapAlgorithm.RSA_OAEP_256.toString()
やKeyWrapAlgorithm.RSA1_5.toString()
を指定してもうまく動きました。以下のドキュメントをみると良いのかもしれません。
作成したEncryptedBlobClient
のupdateStringData
メソッドを使ってデータをBlobとして保存します。
encryptedBlobHelper.updateStringData("This is a sample string2");
この状態でAzure Storage Blobを確認します。
メタデータにencryptiondata
というのが書かれています。ドキュメントを見るとこれらのメタデータは削除してはいけないようです。
このデータをダウンロードして中身をみてみると、暗号化されているようです。
EncryptedBlobClient
のdownloadBlobData
メソッドを使って復号化された状態でファイルがダウンロードできます。
encryptedBlobHelper.downloadBlobData("ファイル名");
ダウンロードしたファイルを見てみると、復号化できているようです。