すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB RDS:EncJDBC

最終更新日:Aug 22, 2026

EncJDBC は、Java アプリケーションが完全暗号化データベースに接続し、クエリロジックを変更することなく、暗号化された列のデータを透過的に復号するための JDBC ドライバーです。

マスター暗号化キー (MEK) を設定すると、EncJDBC は自動的に暗号文を復号し、プレーンテキストをアプリケーションに返します。暗号化と復号のプロセスは、アプリケーションコードからは見えません。

仕組み

EncJDBC は 2 段階のプロセスを使用します。

  1. 接続時に、EncJDBC はエンベロープ暗号化を使用して MEK をサーバーに配布し、キーがプレーンテキストで送信されないようにします。

  2. クエリごとに、EncJDBC は暗号化対象列のパラメーターを自動的に暗号化し、結果を復号してからアプリケーションに返します。

アプリケーションコードは、引き続きプレーンテキスト値を扱います。クエリロジックの変更は不要です。

前提条件

開始する前に、以下をご確認ください:

  • お使いの ApsaraDB RDS for MySQL インスタンスで完全暗号化データベース機能が有効になっていること。詳細については、「完全暗号化データベース機能の有効化」をご参照ください。

  • インスタンスの接続情報 (ホスト名、ポート、データベース名、ユーザー名、パスワード)

  • データ保護ルールが設定されていること。詳細については、「データ保護ルールの設定」をご参照ください。

  • JDK 1.8 以降

このトピックの例では、Maven 3.9.2 と IntelliJ IDEA Community Edition 2022.3.2 を使用しています。
警告

MEK は安全に保管し、決して公開しないでください。紛失した場合、暗号化されたデータは永久にアクセスできなくなります。お使いの RDS インスタンスは、MEK を生成、保存、またはバックアップすることはありません。

Maven 依存関係の追加

プロジェクトの pom.xml ファイルに以下の依存関係を追加します。

<dependencies>
  <dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-encdb-mysql-jdbc</artifactId>
    <version>1.0.9-1</version>
  </dependency>
</dependencies>

設定と接続

EncJDBC は、JDBC URL 形式 jdbc:mysql:encdb://{hostname}:{port}/{dbname} とドライバークラス com.aliyun.encdb.mysql.jdbc.EncDriver を使用します。

接続する前に、2 つの必須パラメーターを設定します。

パラメーター 値の例 説明
MEK 00112233445566778899aabbccddeeff お客様が生成および管理するマスター暗号化キー (MEK) です。有効な値:32 文字の 16 進数文字列 (16 バイト)。openssl rand -hex 16、言語の乱数関数、または Key Management Service (KMS) を使用して生成します。
ENC_ALGO SM4_128_CBC 暗号化アルゴリズムです。デフォルト:SM4_128_GCM

対応暗号化アルゴリズム:

カテゴリ アルゴリズム
AES (国際標準) AES_128_GCMAES_128_CTRAES_128_CBCAES_128_ECB (非推奨)
SM4 (中国国家標準) SM4_128_GCM (デフォルト)、SM4_128_CTRSM4_128_CBCSM4_128_ECB (非推奨)
AES_128_ECBSM4_128_ECB は使用しないでください。これらのモードは強力なセキュリティを保証しません。

EncJDBC への設定の指定

方法は 3 つあります。複数の方法でパラメーターを設定した場合、以下の優先順位が適用されます。[JDBC プロパティ] > [設定ファイル] > [URL パラメーター]。

複数のパラメーターを & で連結できます。

オプション 1:JDBC プロパティ

接続を開く前に、Properties オブジェクトで MEKENC_ALGO を直接設定します。

// プレースホルダーを実際のインスタンス接続情報に置き換えます。
String hostname = "<hostname>";
String port     = "<port>";
String dbname   = "<dbname>";
String username = "<username>";
String password = "<password>";

String mek     = "<your-mek>";   // 32 文字の 16 進数文字列
String encAlgo = "<enc-algo>";   // 例:SM4_128_GCM

Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
props.setProperty("ENC_ALGO", encAlgo);

String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, props);

オプション 2:設定ファイル

以下の内容で設定ファイルを作成します。

MEK=<your-mek>
ENC_ALGO=<enc-algo>

ファイルを以下のいずれかの場所に配置します。

  • プロジェクトの resources ディレクトリ

  • プロジェクトのルートディレクトリ (実行時の作業ディレクトリ)

デフォルトのファイル名は encjdbc.conf です。カスタムパスを使用するには、システムプロパティ encJdbcConfigFile を設定ファイルのディレクトリに設定します。

ファイルを配置した後、コードで MEK または ENC_ALGO を指定せずに接続します。

String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, username, password);

オプション 3:URL パラメーター

MEKENC_ALGO を JDBC URL に直接追加します。

String dbUrl = String.format(
    "jdbc:mysql:encdb://%s:%s/%s?MEK=%s&ENC_ALGO=%s",
    hostname, port, dbname, mek, encAlgo
);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, username, password);

コード例

以下の例では、JDBC プロパティを使用して接続し、テーブルに行を挿入して、プレーンテキストで結果を取得します。

// プレースホルダーを実際のインスタンス接続情報に置き換えます。
String hostname = "hostname";
String port     = "port";
String dbname   = "db";
String username = "user";
String password = "password";

// 本番環境では、ランダムに生成された強力な MEK を使用してください。
String mek     = "00112233445566778899aabbccddeeff";
String encAlgo = "SM4_128_CBC";

Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
props.setProperty("ENC_ALGO", encAlgo);

String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, props);

int[]    intData = {1, 2, 3, 4, 5, 6};
String[] strData = {"abc", "bcd", "1", "def", "efg", "fgi"};

// テーブルを作成します。
connection.createStatement().executeUpdate("drop table if exists test");
connection.createStatement().executeUpdate("create table test (a int, b text)");

// PreparedStatement を使用して行を挿入します。
// EncJDBC は、暗号化対象列の値を自動的に暗号化します。
for (int i = 0; i < 6; i++) {
    PreparedStatement pstmt = connection.prepareStatement("insert into test values (?,?)");
    pstmt.setInt(1, intData[i]);
    pstmt.setString(2, strData[i]);
    pstmt.executeUpdate();
}

// 行をクエリします。EncJDBC は、結果を返す前に自動的に復号します。
ResultSet rs = connection.prepareStatement("select * from test").executeQuery();
while (rs.next()) {
    for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
        System.out.print(rs.getString(i + 1));
        System.out.print("\t");
    }
    System.out.print("\n");
}

出力例:

1	abc
2	bcd
3	1
4	def
5	efg
6	fgi

以下の点にご注意ください:

  • 暗号化された列に対するすべての読み取りと書き込みは、PreparedStatement を使用します。ドライバーはパラメーターを自動的に暗号化し、結果を復号します。クエリロジックの変更は必要ありません。

  • 暗号化されていない列に渡された値は影響を受けません。

トラブルシューティング

IllegalAccessError: cannot access class com.sun.crypto.provider.SunJCE

このエラーは、新しいバージョンの JDK ではデフォルトでモジュール間のアクセスが制限されているために発生します。プログラムの実行時に、以下の VM オプションを追加してください。

--add-exports=java.base/com.sun.crypto.provider=ALL-UNNAMED

failed in mek provision: gcmEncrypt error

これは Oracle JDK の既知の問題です。以下のいずれかの修正を適用してください。

  • Amazon Corretto への切り替え — この問題が発生しない、ドロップインの OpenJDK ディストリビューションです。

  • Oracle JDK への BouncyCastle セキュリティプロバイダーの追加:

    1. JDK のインストールディレクトリを見つけます。

    2. <jdk-path>/conf/security/java.security を開きます。

    3. List of providers and their preference orders セクションに、security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider を追加します。