All Products
Search
Document Center

Database Autonomy Service:Integrate EncJDBC for column encryption

Last Updated:Mar 28, 2026

EncJDBC is a JDBC wrapper driver that brings transparent column-level decryption to Java applications. Drop it in, point it at your encrypted ApsaraDB RDS instance, and your existing SQL queries return plaintext — no application-level decryption code required.

How it works

EncJDBC sits between your application and the database driver. When you open a connection, the driver uses your Master Encryption Key (MEK) to negotiate a secure session with the database server via asymmetric key exchange. All subsequent data transfer uses symmetric encryption. Encrypted column values are decrypted on the client before being handed to your application code.

The MEK never leaves your environment unprotected — it is distributed to the server using envelope encryption.

Prerequisites

Before you begin, ensure that you have:

  • Completed a sensitive data detection scan to identify columns to encrypt. For more information, see Sensitive data detection.

  • Enabled column encryption for the target database and granted the Ciphertext Permission (JDBC Decryption) to the target database account. For more information, see Column encryption.

  • The connection details for the RDS instance with always-confidential database enabled: hostname, port, database name, username, and password.

  • JDK 1.8 or later installed

Choose a key type

EncJDBC supports two key management approaches. Choose one before proceeding — your choice determines how you generate and configure the MEK.

KMS keyLocal key
Key storageManaged by Alibaba Cloud Key Management Service (KMS)Stored and managed by you
Key rotationSupported via KMSManual
Network dependencyRequires KMS service availabilityNone
Setup complexityRequires AccessKey pair and KMS endpointMinimal — generate a hex string
Best forProduction workloads requiring centralized key managementDevelopment, testing, or air-gapped environments

Generate an MEK

The MEK is a 32-character hexadecimal string (16 bytes). Generate one using your operating system's cryptographic tools:

  • Linux (OpenSSL is pre-installed): openssl rand -hex 16

  • Windows: Install the OpenSSL package, then run the same command.

Example output: 00112233445566778899aabbccddeeff

Warning

The always-confidential database feature does not generate, store, or back up your MEK. Store it securely and back it up — losing the MEK means losing access to your encrypted data.

If you chose a KMS key, the MEK is the KMS-managed key itself. Complete the KMS setup steps below before configuring the client. If you chose a local key, skip ahead to Add the Maven dependency.

Set up KMS key access

Important

If the KMS service is unavailable, EncJDBC cannot decrypt data. Confirm that KMS is reachable from your application environment before using this option.

To let EncJDBC read the KMS-managed key, you need the KMS instance endpoint and an AccessKey pair with decryption permission.

Step 1: Grant KMS decryption permission (RAM users only)

If connecting as a RAM user, attach a custom policy granting KMS:Decrypt:

  1. Create a custom policy. For more information, see Create custom policies. Use the following policy document:

    {
        "Version": "1",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "KMS:Decrypt",
                "Resource": "*"
            }
        ]
    }
  2. Attach the policy to the RAM user. For more information, see Grant permissions to a RAM user.

Step 2: Get the KMS instance endpoint

KMS keys are accessible only over virtual private cloud (VPC) networks by default.

  • VPC access: Go to the KMS console. On the Instance page, click Details in the Actions column. On the Instance tab, copy the Instance VPC Endpoint value.

image
  • Public internet access: On the Share Resources tab, enable Internet Access Status, then copy the Public Endpoint value.

image

Step 3: Create an AccessKey pair

Create an AccessKey pair for the Alibaba Cloud account or RAM user. Save both the AccessKey ID and AccessKey secret. For more information, see Create an AccessKey.

Store the credentials as environment variables — never hardcode them in application code:

export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-access-key-id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-access-key-secret>

For more information on setting environment variables, see Configure environment variables in Linux, macOS, and Windows.

Add the Maven dependency

Add EncJDBC to your pom.xml:

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-cls-jdbc</artifactId>
    <version>1.0.10-1</version>
</dependency>

Connect to the database

Switch the JDBC driver class and connection URL from the standard MySQL or PostgreSQL driver to the EncJDBC equivalents, then supply the MEK.

DatabaseDriver classConnection URL format
MySQLcom.aliyun.encdb.mysql.jdbc.EncDriverjdbc:mysql:encdb://<host>:<port>/<dbname>
PostgreSQLcom.aliyun.encdb.postgresql.jdbc.EncDriverjdbc:postgresql:encdb://<host>:<port>/<dbname>

EncJDBC supports three ways to pass the MEK. If you configure more than one, they are applied in this priority order: JDBC properties > configuration file > URL parameter.

Option 1: JDBC properties (recommended)

Passing the MEK through Properties keeps credentials out of the URL and supports Security Token Service (STS) temporary credentials.

KMS key

String hostname = "<your-hostname>";
String port     = "<your-port>";
String dbname   = "<your-database-name>";
String username = "<your-username>";
String password = "<your-password>";

// Read credentials from environment variables — never hardcode them.
String accessKeyId     = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// For STS temporary credentials, also read the security token:
// String stsToken = System.getenv("ALIBABA_CLOUD_STS_TOKEN");

// Use the VPC endpoint for VPC access, or the public endpoint for internet access.
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);

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);

For STS temporary credentials, see STS SDK overview.

Local key

String hostname = "<your-hostname>";
String port     = "<your-port>";
String dbname   = "<your-database-name>";
String username = "<your-username>";
String password = "<your-password>";
String mek      = "00112233445566778899aabbccddeeff"; // Replace with your generated MEK.

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);
// For PostgreSQL, use: jdbc:postgresql:encdb://%s:%s/%s
// and load: com.aliyun.encdb.postgresql.jdbc.EncDriver
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, props);

Option 2: Configuration file (local key only)

Note

The file configuration method is only supported for local key MEK.

Create a file named encjdbc.conf with the following content:

MEK=00112233445566778899aabbccddeeff

Place the file in one of these locations:

  • The resources/ directory of your project:

    image

  • The project root directory (the program's runtime directory).

To use a custom file path, set the encJdbcConfigFile property to the file path.

With the configuration file in place, no additional code changes are needed:

String hostname = "<your-hostname>";
String port     = "<your-port>";
String dbname   = "<your-database-name>";
String username = "<your-username>";
String password = "<your-password>";

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);

Option 3: URL parameter

Embed the MEK directly in the connection URL. Use & to concatenate multiple parameters.

KMS key

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
);
// With STS token:
// "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"

Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, username, password);

Local key

String dbUrl = String.format(
    "jdbc:mysql:encdb://%s:%s/%s?MEK=%s",
    hostname, port, dbname, mek
);
// For PostgreSQL: jdbc:postgresql:encdb://%s:%s/%s?MEK=%s

Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, username, password);

Query encrypted columns

After the connection is established, query the database with standard JDBC. EncJDBC automatically decrypts encrypted columns and returns plaintext.

Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table_name");

while (resultSet.next()) {
    for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
        System.out.print(resultSet.getString(i));
        System.out.print("\t");
    }
    System.out.println();
}

Troubleshooting

IllegalAccessError: SunJCE module access denied

Full error: java.lang.IllegalAccessError: class com.alibaba.encdb.common.SymCrypto ... cannot access class com.sun.crypto.provider.SunJCE

This happens when the JDK module system blocks access to com.sun.crypto.provider. Add the following VM option when running your program:

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

gcmEncrypt error: MEK provision failed

Full error: failed in mek provision: you might have an incorrect mek setting. Detail:gcmEncrypt error

This is a known issue with Oracle JDK. Two options:

  • Switch to Amazon Corretto — this resolves the issue without additional configuration.

  • Register BouncyCastle as a security provider in Oracle JDK:

    1. Locate the JDK installation directory.

    2. Open <installation-path>/conf/security/java.security.

    3. Under the List of providers and their preference orders section, add:

      security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider

What's next

  • Learn more about the always-confidential database feature and supported encryption algorithms: Column encryption.

  • Manage and rotate your MEK: Key management.