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

Data Security Center:EncJDBC の統合

最終更新日:Aug 25, 2026

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

前提条件

  • 対象のデータベースで列の暗号化が有効になっており、対象のデータベースアカウントの暗号文権限が 暗号文権限 (復号) に設定されている必要があります。データベースの列の暗号化とアカウント権限の設定に関する詳細な手順については、「データベースの列の暗号化を設定」をご参照ください。

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

背景情報

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

  • プレーンテキスト権限 を持つアカウントは、生データを直接表示できます。

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

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

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

MEK の生成

列に対して [ローカルキー] 方式を使用して列の暗号化を有効にすると、DSC 列暗号化ゲートウェイは、クエリ結果をクライアントに返す前に、管理されたキーを使用して機密フィールドを暗号化します。[プレーンテキスト権限] を持つアカウントを除き、他のすべてのアカウントは、その列をクエリするときに暗号化された暗号文を受信します。

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

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

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

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

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

データベースの列の暗号化設定で選択した 暗号化方式 に基づいて、KMS キー を取得するか、ローカルキー を生成して、対応するデータベースを復号するための MEK として使用します。

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 インスタンスを見つけ、操作 列の 詳細 をクリックし、基本情報 タブで VPC エンドポイントを表示します。

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

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

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

ローカルキー

データベースの列の暗号化設定の 暗号化方式ローカルキー に設定されている場合は、MEK を生成してください。例:00112233445566778899aabbccddeeff。

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

例:

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

  • Windows では、OpenSSL ソフトウェアパッケージをインストールしてください。

クライアント統合手順

重要

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

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

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

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

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-enc-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 という名前の プロパティ を設定し、その値を設定ファイルのパスに設定できます (デフォルトでは、ファイル 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 を設定し、暗号文権限 (復号) を持つデータベースアカウントを使用して、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