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

Data Security Center:EncJDBC の統合

最終更新日:Jun 22, 2026

RDS MySQL、RDS PostgreSQL、PolarDB MySQL、または PolarDB PostgreSQL のデータベーステーブルで機密データ列に列レベルの暗号化を設定した後、Java アプリケーションからこれらの暗号化された列のプレーンテキストにアクセスするには、EncJDBC ドライバーを使用してデータベースに接続します。このトピックでは、EncJDBC を使用してデータベースに接続し、暗号化された列からプレーンテキストデータにアクセスする方法について説明します。

前提条件

  • ターゲットデータベースの列の暗号化を有効にし、ターゲットデータベースアカウントの暗号文の権限を Ciphertext Permission (JDBC Decryption) に設定します。データベースの列の暗号化とアカウントの権限の設定に関する詳細については、「データベースの列の暗号化を設定する」をご参照ください。

  • 暗号化されたデータベースの接続情報 (エンドポイント、ポート、データベース名、データベースアカウント、パスワード) を取得しておきます。

背景情報

列レベルの暗号化機能を使用すると、データベース内の特定の機密列に動的な出力保護を適用し、データセキュリティを向上させることができます。この機能を有効にすると、システムはデータベースアカウントのアクセスポリシーに基づいてクエリ結果を制御します。

  • Plaintext Permissions を持つアカウントは、生データを直接閲覧できます。

  • Ciphertext Permission (JDBC Decryption) が設定されたアカウントは、暗号化された暗号文を受信しますが、Alibaba Cloud の常時機密 JDBC ドライバー (EncJDBC) を使用し、暗号化ポリシーに一致するマスター暗号化キー (MEK) を提供することで、それを自動的に平文に復元できます。

  • Ciphertext Permission (No Decryption Permission) が設定されたアカウントは、暗号文のみ表示でき、いかなる方法でも復号することはできません。

このメカニズムにより、機密データが出力段階で効果的に保護されます。データがエクスポートされたり傍受されたりした場合でも、権限のない第三者がそれを読み取ることはできません。

MEK の生成

列に対して 「ローカルキー」 方式を使用して列レベルの暗号化を有効にすると、Data Security Center (DSC) の列暗号化ゲートウェイは、クエリ結果をクライアントに返す前に、制御されたキーを使用して機密フィールドを暗号化します。「プレーンテキスト権限」 を持つアカウントを除き、他のすべてのアカウントは、その列をクエリすると暗号化された暗号文を受け取ります。

後で「暗号文権限 (JDBC 復号)」を持つアカウントを使用してプレーンテキストにアクセスするには、最初の列レベルの暗号化設定時に独自の MEK を提供し、記録しておく必要があります。暗号化ポリシーに一致する MEK を使用することによってのみ、EncJDBC ドライバーはクライアント側でクエリ結果の暗号文フィールドを正しく復号できます。

  • 値の範囲:長さが正確に 32 文字の 16 バイトの 16 進数文字列です。

  • MEK の役割:MEK は、EncJDBC クライアントがクエリ結果の暗号文フィールドを復号することを承認するルート認証情報です。クエリ結果の暗号化に使用される実際のキーを保護します。

  • セキュリティ責任:Alibaba Cloud はお客様の MEK を保存、バックアップ、または保持しません。KMS などの安全なキー管理ソリューションを使用して保護してください。

  • 重要な警告:MEK を紛失した場合、このポリシーで暗号化されたすべての過去のクエリ結果は 永久に復号不可 となります。

データベース列の暗号化設定で選択したEncryption Methodに基づき、対応するデータベースを復号化するための MEK として、KMS Keyを取得するか、Local Keyを生成します。

KMS キー

重要

KMS キーを使用する際は、KMS サービスが利用できることを確認してください。利用できない場合、常時機密クライアントドライバー EncJDBC は機能しません。

データベースの列レベルの暗号化設定で選択した 「KMS キー」 を所有する KMS インスタンスのエンドポイントと、クライアントからこの KMS キーを読み取るための Alibaba Cloud アカウントまたは RAM ユーザー (KMS の復号権限が必要です) の AccessKey ID と AccessKey シークレットを取得します。次の手順に従ってください。

  1. Alibaba Cloud アカウントまたはRAM ユーザーを使用してコンソールにログインします。

  2. RAM ユーザーを使用する場合は、RAM ユーザーに KMS の復号権限を付与します。

    1. カスタムポリシーを作成します。次のポリシー内容を使用します。

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "KMS:Decrypt",
                  "Resource": "*"
              }
          ]
      }
    2. 作成したカスタムポリシーを特定の RAM ユーザーにアタッチします。詳細については、「RAM ユーザーの権限を管理する」をご参照ください。

  3. KMS インスタンスのエンドポイントを取得します。

    • デフォルトでは、KMS インスタンスのキーには、VPC ネットワークからのみアクセスできます。KMS インスタンス管理ページで目的の KMS インスタンスを見つけ、アクションDetails の順にクリックし、Basic Information タブで VPC エンドポイントを表示します。

    • パブリックネットワーク経由でキーにアクセスするには、パブリックネットワークアクセスを有効にしてからパブリックエンドポイントを表示します。詳細については、「パブリックネットワークアクセスを有効にする」をご参照ください。

  4. アクセス認証情報を取得します。

    Alibaba Cloud アカウントまたは RAM ユーザーの AccessKey を作成する際に、AccessKey ID と AccessKey シークレットを保存しておいてください。詳細については、「AccessKey の作成」をご参照ください。

ローカルキー

データベース列の暗号化設定の Encryption MethodLocal Key に設定されている場合、MEK を生成します。例: 00112233445566778899aabbccddeeff。

一般的な生成方法には、パスワードジェネレーターやプログラミング言語の乱数関数などがあります。

例:

  • Linux では、組み込みの OpenSSL ツールを使用し、openssl rand -hex 16 を実行してキーを生成します。

  • Windows では、OpenSSL ソフトウェアパッケージをインストールします。

クライアント統合手順

重要

Java は JDK 1.8 以降を使用してください。

クライアント側で、データベース接続ドライバーを EncJDBC に切り替え、データベース接続 URL を更新し、暗号化されたデータベース列からプレーンテキストにアクセスするために MEK を指定します。

1. 依存関係のインストール

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

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-encdb-jdbc</artifactId>
    <version>1.0.10-3</version>
</dependency>

2. MEK がデータベースに接続するように設定する

MEK の設定方法には、JDBC プロパティ設定、ファイル設定、URL 設定があります。複数の方法を同時に設定した場合、優先順位は JDBC プロパティ設定 > ファイル設定 > URL 設定となります。

説明
  • URL 設定では、複数のパラメータを & で区切ります。

  • 以下のすべての構成および接続方法では、MEK はクライアントでローカルに処理され、エンベロープ暗号化を使用してサーバーに安全に送信されることで、MEK の漏洩が防止されます。

データベースの列レベルの暗号化設定の 「暗号化方式」 に応じて、ローカルキーまたは KMS キーのいずれかを使用してデータベースに接続します。

KMS キーを使用したデータベース接続

重要
  • STS 一時的な認証情報を使用して KMS 管理の MEK を取得する場合は、STS SDK を使用して一時的な認証情報 STS トークンを取得してください。STS SDK の例については、「STS SDK の概要」をご参照ください。

  • アクセス認証情報 (AccessKey ID および AccessKey シークレット) をアプリケーションコードに直接ハードコードしないでください。この例では、システム環境変数を使用してアクセス認証情報を管理します。詳細については、「Linux、macOS、および Windows で環境変数を設定する」をご参照ください。

JDBC プロパティ設定

標準 JDBC では、接続時に Properties を使用してカスタムプロパティを設定できます。次の例は、JDBC プロパティを設定して JDBC を実行する方法を示しています。

// ホスト名、ポート、データベース名、ユーザー名、パスワードなどの接続情報を準備します。
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// 環境変数からアクセス認証情報 (AccessKey ID と AccessKey シークレット) を取得します。
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// STS 一時的な認証情報を使用して KMS キーを読み取る場合は、取得した STS トークンも指定します。
// String stsToken = "yourSecurityToken";
// KMS インスタンスのエンドポイント。パブリックネットワークアクセスが有効な場合はパブリックエンドポイントを、VPC アクセスの場合は VPC エンドポイントを使用します。
String kmsEndpoint = "kms.cn-hangzhou.aliyuncs.com";
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("ALIBABA_CLOUD_ACCESS_KEY_ID", accessKeyId);
props.setProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET", accessKeySecret);
props.setProperty("ALIBABA_CLOUD_KMS_ENDPOINT", kmsEndpoint);
// props.setProperty("ALIBABA_CLOUD_STS_TOKEN", stsToken);
// MySQL の接続 URL 形式:「jdbc:mysql:encdb://%s:%s/%s」
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
// MySQL 用の EncJDBC ドライバーをロードします。
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// データベース接続を取得します。
Connection connection = DriverManager.getConnection(dbUrl, props);
// ... クエリを実行 ...
URL 設定

以下に示すように、KMS キーを取得するためのパラメータを URL に直接埋め込むことができます。

// ホスト名、ポート、データベース名、ユーザー名、パスワードなどの接続情報を準備します。
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// 環境変数からアクセス認証情報 (AccessKey ID と AccessKey シークレット) を取得します。
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// STS 一時的な認証情報を使用して KMS キーを読み取る場合は、取得した STS トークンも指定します。
// String stsToken = "yourSecurityToken";
// KMS インスタンスのエンドポイント。パブリックネットワークアクセスが有効な場合はパブリックエンドポイントを、VPC アクセスの場合は VPC エンドポイントを使用します。
String kmsEndpoint = "kms.cn-hangzhou.aliyuncs.com";
// MySQL の接続 URL 形式。
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?ALIBABA_CLOUD_ACCESS_KEY_ID=%s&ALIBABA_CLOUD_ACCESS_KEY_SECRET=%s&ALIBABA_CLOUD_KMS_ENDPOINT=%s", hostname, port, dbname, accessKeyId, accessKeySecret, kmsEndpoint);
// STS トークンを使用する場合。
// String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?ALIBABA_CLOUD_ACCESS_KEY_ID=%s&ALIBABA_CLOUD_ACCESS_KEY_SECRET=%s&ALIBABA_CLOUD_KMS_ENDPOINT=%s&ALIBABA_CLOUD_STS_TOKEN=%s", hostname, port, dbname, accessKeyId, accessKeySecret, kmsEndpoint, stsToken);
// MySQL 用の EncJDBC ドライバーをロードします。
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// データベース接続を取得します。
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... クエリを実行 ...

ローカルキーを使用したデータベース接続

JDBC プロパティ設定

標準 JDBC では、接続時に Properties を使用してカスタムプロパティを設定できます。次の例は、JDBC プロパティを設定して JDBC を実行する方法を示しています。

// ホスト名、ポート、データベース名、ユーザー名、パスワードなどの接続情報を準備します。
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// マスター暗号化キー。
String mek = "00112233445566778899aabbccddeeff"; 
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
// MySQL の接続 URL 形式:「jdbc:mysql:encdb://%s:%s/%s」。PostgreSQL の場合は、「jdbc:postgresql:encdb://%s:%s/%s」を使用します。
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
// MySQL 用の EncJDBC ドライバーをロードします。PostgreSQL の場合は、「com.aliyun.encdb.postgresql.jdbc.EncDriver」を使用します。
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// データベース接続を取得します。
Connection connection = DriverManager.getConnection(dbUrl, props);
// ... クエリを実行 ...
ファイル設定

必要な MEK などのパラメータを設定ファイルからインポートできます。

説明

ファイル設定はローカルキーの MEK にのみ適用されます。

プロジェクトに encJdbcConfigFile という名前の property を設定し、その値に設定ファイルのパスを指定できます (デフォルトでは、ファイル encjdbc.conf が使用されます)。 設定ファイルの内容は次のとおりです:

MEK=00112233445566778899aabbccddeeff

設定ファイルは、次の 2 つの場所のいずれかに配置できます。

  • 以下のように、プロジェクトのリソースディレクトリにファイルを配置します。

    src
      main
        java
        resources
          encjdbc.conf
  • プロジェクトのルートディレクトリ (プログラムの実行時ディレクトリ) にファイルを配置します。

ファイル設定をおこなった後、以下のようにコードに追加の設定は必要ありません。

// ホスト名、ポート、データベース名、ユーザー名、パスワードなどの接続情報を準備します。
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// MySQL の接続 URL 形式:「jdbc:mysql:encdb://%s:%s/%s」。PostgreSQL の場合は、「jdbc:postgresql:encdb://%s:%s/%s」を使用します。
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
// MySQL 用の EncJDBC ドライバーをロードします。PostgreSQL の場合は、「com.aliyun.encdb.postgresql.jdbc.EncDriver」を使用します。
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// データベース接続を取得します。
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... クエリを実行 ...
URL 設定

以下に示すように、MEK などのパラメーターを URL に直接埋め込むことができます。

// ホスト名、ポート、データベース名、ユーザー名、パスワードなどの接続情報を準備します。
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
 // マスター暗号化キー。
String mek = "00112233445566778899aabbccddeeff";
// MySQL の接続 URL 形式:「jdbc:mysql:encdb://%s:%s/%s?MEK=%s」。PostgreSQL の場合は、「jdbc:postgresql:encdb://%s:%s/%s?MEK=%s」を使用します。
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?MEK=%s", hostname, port, dbname, mek);
// MySQL 用の EncJDBC ドライバーをロードします。PostgreSQL の場合は、「com.aliyun.encdb.postgresql.jdbc.EncDriver」を使用します。
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// データベース接続を取得します。
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... クエリを実行 ...

3. 暗号化された列からのプレーンテキストデータのクエリ

データベースへの接続に成功したら、標準の JDBC クエリと同様に操作します。EncJDBC は自動的に暗号化された列を復号し、プレーンテキストデータを返します。

サンプルコード:

// クエリを実行します。
// クエリステートメントを作成します。
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table_name");
// 結果セットを走査します。
while (resultSet.next()) {
    for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {
        System.out.print(resultSet.getString(i + 1));
        System.out.print("\t");
    }
    System.out.print("\n");
}

完全なコード例

この例は、JDBC プロパティを使用してローカルキー MEK を設定し、Ciphertext Permission (JDBC Decryption) を持つデータベースアカウントを使用して RDS MySQL データベース内の暗号化された列からプレーンテキストデータをクエリする方法を示します。

以下の例のデータベース設定については、『RDS MySQL データベースの列レベルの暗号化の例』 の「列レベルの暗号化結果の確認」をご参照ください。

説明

この例では、Maven バージョン 3.9.9 と開発ツール IntelliJ IDEA Community Edition 2024.1.2 を使用します。

import java.sql.*;
import java.util.Properties;
public class EncryptedColumnAccess {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 次の接続情報 (ホスト名、ポート、データベース名、ユーザー名、パスワード) をインスタンスの詳細で更新します。
        String hostname = "rm-******.mysql.rds.aliyuncs.com";
        String port = "3306";
        String dbname = "sddp_em_db";
        String username = "sddp_em03";
        String password = "******";
        // これは一例です。本番環境ではより複雑なキーを使用してください。
        String mek="00112233445566778899aabbccddeeff";
        Properties props = new Properties();
        props.setProperty("user", username);
        props.setProperty("password", password);
        props.setProperty("MEK", mek);
        String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
        // EncJDBC ドライバーをロードします。
        Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
        // データベース接続を取得します。
        Connection connection = DriverManager.getConnection(dbUrl, props);
        // クエリを実行します。
        try {
            // クエリステートメントを作成します。
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("SELECT * FROM users");
            // 結果セットを走査します。
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("username");
                String phone = resultSet.getString("phone");
                // テーブルスキーマに基づいて他のフィールドを処理します。
                System.out.println("ID: " + id + ", Name: " + name + ", Phone: " + phone);
            }
            // リソースを閉じます。
            resultSet.close();
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

出力例:

ID: 1, Name: username008808, Phone: 15xxx95
ID: 2, Name: username187643, Phone: 15xxx81