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 key | Local key | |
|---|---|---|
| Key storage | Managed by Alibaba Cloud Key Management Service (KMS) | Stored and managed by you |
| Key rotation | Supported via KMS | Manual |
| Network dependency | Requires KMS service availability | None |
| Setup complexity | Requires AccessKey pair and KMS endpoint | Minimal — generate a hex string |
| Best for | Production workloads requiring centralized key management | Development, 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 16Windows: Install the OpenSSL package, then run the same command.
Example output: 00112233445566778899aabbccddeeff
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
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:
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": "*" } ] }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.

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

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.
| Database | Driver class | Connection URL format |
|---|---|---|
| MySQL | com.aliyun.encdb.mysql.jdbc.EncDriver | jdbc:mysql:encdb://<host>:<port>/<dbname> |
| PostgreSQL | com.aliyun.encdb.postgresql.jdbc.EncDriver | jdbc: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)
The file configuration method is only supported for local key MEK.
Create a file named encjdbc.conf with the following content:
MEK=00112233445566778899aabbccddeeffPlace the file in one of these locations:
The
resources/directory of your project:
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-UNNAMEDgcmEncrypt 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:
Locate the JDK installation directory.
Open
<installation-path>/conf/security/java.security.Under the
List of providers and their preference orderssection, 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.