Java アプリケーションを使用して ApsaraDB RDS for PostgreSQL インスタンス上の暗号化された列にアクセスする場合、Alibaba Cloud が提供する JDBC ベースの列暗号化ドライバを使用できます。必要なマスター暗号鍵(MEK)があれば、JDBC ベースの列暗号化ドライバは暗号文データを自動的に復号化し、プレーンテキストデータを返します。このプロセスはアプリケーションに対して透過的であり、アプリケーションコードを少し変更するだけで、アプリケーションを暗号化された列に接続できます。
前提条件
列暗号化機能が有効になっていること。
説明列暗号化機能を有効にすると、システムは RDS インスタンスに rds_encdb 拡張機能を自動的にインストールします。
SELECT EXISTS (SELECT * FROM pg_extension WHERE extname = 'rds_encdb');SQL 文を実行して、rds_encdb 拡張機能のステータスをクエリできます。列暗号化が有効になっている RDS インスタンスの接続情報を取得していること。接続情報には、エンドポイント(ホスト)、ポート番号(ポート)、インスタンス名(dbname)、ユーザー名(username)、およびパスワード(password)が含まれます。RDS インスタンスの内部エンドポイントとパブリックエンドポイントを取得する方法の詳細については、「エンドポイントとポート番号の表示と変更」をご参照ください。
[暗号文権限(JDBC 復号)] が必要なアカウントに付与されていること。詳細については、「列暗号化機能の使用」をご参照ください。
使用上の注意
MEKを保存し、機密性を保持する必要があります。JDK 1.8 以降を使用します。
手順
この例では、Java プロジェクトは Maven を使用して設定されています。
ステップ 1:Maven の依存関係を設定する
Maven プロジェクトの pom.xml ファイルに次の依存関係を追加します。
<dependencies>
...
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-cls-jdbc</artifactId>
<version>1.0.10-1</version>
</dependency>
...
</dependencies>ステップ 2:URL と MEK を設定する
JDBC ベースの列暗号化ドライバを使用して暗号化された列にアクセスする前に、RDS インスタンスへの接続に使用する MEK と URL を含む、必要なパラメーターを設定する必要があります。
設定またはパラメーター | 例(文字列型) | 説明 |
MEK | 00112233445566778899aabbccddeeff | データ所有者によって指定された MEK。
警告 MEK は、暗号化されたデータにアクセスするために使用するルート資格情報です。セキュリティ上の理由から、RDS インスタンスは MEK を生成、保存、管理、またはバックアップしません。MEK を生成し、機密性を保持する必要があります。MEK を紛失した場合、既存の暗号化データにアクセスできなくなります。MEK をバックアップすることをお勧めします。 |
URL | jdbc:postgresql:encdb://%s:%s/%s | JDBC ベースの列暗号化ドライバを使用する場合は、 |
MEK を設定する
このセクションでは、MEK を設定するために使用できる方法について説明します。JDBC ベースの列暗号化ドライバのパラメーターを設定するために複数の方法を使用する場合、JDBC プロパティ設定、設定ファイル、URL 設定の順に優先されます。
URL 設定方法を使用する場合は、アンパサンド(
&)を使用して複数のパラメーターを連結できます。以下の方法では、
MEKはクライアント側で設定され、エンベロープ暗号化を使用してサーバーに配布されるため、MEKが漏洩することはありません。
JDBC プロパティ設定
標準 JDBC インターフェースから RDS インスタンスに接続する場合、Properties パラメーターを設定してカスタムプロパティを指定できます。コマンド例:
// エンドポイント(hostname)、ポート番号(port)、インスタンス名(dbname)、ユーザー名(username)、パスワード(password)などの接続情報を取得します。
// ...
String mek=****;
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s", hostname, port, dbname);
Connection connection = DriverManager.getConnection(dbUrl, props);
// ... クエリを開始します。 ...ファイル設定
MEK などの必要なパラメーターをインポートするために設定ファイルを使用できます。プロジェクトで encJdbcConfigFile という名前のプロパティを定義し、プロパティの値を設定ファイルのディレクトリに設定する必要があります。プロパティの値を指定しない場合、encjdbc.conf ファイルがプロパティに自動的に使用されます。
次のコードスニペットは、設定ファイルの内容を示しています。
MEK=****設定ファイルは、次のいずれかのディレクトリに保存できます。
プロジェクトのリソースディレクトリ。

プロジェクトのルートディレクトリ。ルートディレクトリは、アプリケーションが実行時に使用するディレクトリです。
設定ファイルメソッドを使用して MEK を設定した後、アプリケーションに追加の設定は必要ありません。コード例:
// エンドポイント(hostname)、ポート番号(port)、インスタンス名(dbname)、ユーザー名(username)、パスワード(password)などの接続情報を取得します。
// ...
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s", hostname, port, dbname);
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... クエリを開始します。 ...URL 設定
URL で MEK パラメーターと ENC_ALGO パラメーターを設定できます。コード例:
// エンドポイント(hostname)、ポート番号(port)、インスタンス名(dbname)、ユーザー名(username)、パスワード(password)などの接続情報を取得します。
// ...
String mek=****;
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s?MEK=%s", hostname, port, dbname, mek);
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... クエリを開始します。 ...完全なサンプルコード
次のコードスニペットは、JDBC プロパティを使用して MEK を設定する方法を示しています。JDBC ベースの列暗号化ドライバを使用して暗号化された列にアクセスする前に、RDS インスタンスで列暗号化設定を完了する必要があります。
package org.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class Main {
public static void main(String[] args) throws SQLException {
// ビジネス要件に基づいて、hostname、port、dbname、username、password などの接続情報を更新します。
String hostname = "pgm-****.pg.rds.aliyuncs.com"; // RDS インスタンスのエンドポイント。実際のエンドポイントを使用する必要があります。
String port = "5432"; // データベースのポート番号。実際のポート番号を使用する必要があります。
String dbname = "testdb"; // データベースの名前。実際のデータベース名を使用する必要があります。
String username = "user"; // データベースにログインするために使用するアカウントのユーザー名。暗号文権限(JDBC 復号)を持つユーザーの名前を使用する必要があります。
String password = "password"; // データベースにログインするために使用するアカウントのパスワード。
// サンプル MEK。セキュリティを確保するために、強力な MEK を使用することをお勧めします。
String MEK = "00112233445566778899aabbccddeeff";
// データベース接続プロパティを作成します。
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", MEK);
// データベースに接続するために使用する URL をフォーマットします。
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s", hostname, port, dbname);
// DriverManager を使用してデータベース接続を取得します。
Connection connection = DriverManager.getConnection(dbUrl, props);
// クエリを実行して、test テーブルのデータを取得します。
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM test_table");
while (rs.next()) {
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { // 列インデックスは 1 から始まります。
System.out.print(rs.getString(i) + "\t");
}
System.out.println(); // 改行。
}
// リソースを無効にします。
rs.close(); // 結果セットを閉じます。
connection.close(); // 接続を閉じます。
}
}