All Products
Search
Document Center

ApsaraDB RDS:EncJDBC

Last Updated:Mar 28, 2026

EncJDBC is a JDBC driver that lets Java applications connect to an always-confidential database and transparently decrypt encrypted column data—without changing your query logic.

With the master encryption key (MEK) configured, EncJDBC automatically decrypts ciphertext and returns plaintext to your application. The encryption and decryption process is invisible to your application code.

How it works

EncJDBC uses a two-step process:

  1. At connection time, EncJDBC distributes your MEK to the server using envelope encryption, ensuring the key is never transmitted in plaintext.

  2. For each query, EncJDBC automatically encrypts parameters targeting encrypted columns and decrypts results before returning them to your application.

Your application code continues to work with plaintext values—no changes to query logic are needed.

Prerequisites

Before you begin, ensure that you have:

The examples in this topic use Maven 3.9.2 and IntelliJ IDEA Community Edition 2022.3.2.
Warning

Store your MEK securely and never expose it. If lost, the encrypted data becomes permanently inaccessible. Your RDS instance never generates, stores, or backs up your MEK.

Add the Maven dependency

Add the following dependency to the pom.xml file of your project:

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

Configure and connect

EncJDBC uses the JDBC URL format jdbc:mysql:encdb://{hostname}:{port}/{dbname} and the driver class com.aliyun.encdb.mysql.jdbc.EncDriver.

Before connecting, configure two required parameters:

ParameterExample valueDescription
MEK00112233445566778899aabbccddeeffThe master encryption key (MEK) that you generate and manage. Valid value: a 32-character hexadecimal string (16 bytes). Generate one using openssl rand -hex 16, a language's random function, or Key Management Service (KMS).
ENC_ALGOSM4_128_CBCThe encryption algorithm. Default: SM4_128_GCM.

Supported encryption algorithms:

CategoryAlgorithms
AES (internationally accepted)AES_128_GCM, AES_128_CTR, AES_128_CBC, AES_128_ECB (not recommended)
SM4 (Chinese national standard)SM4_128_GCM (default), SM4_128_CTR, SM4_128_CBC, SM4_128_ECB (not recommended)
Avoid AES_128_ECB and SM4_128_ECB—these modes do not provide strong security guarantees.

Pass configuration to EncJDBC

Three methods are available. If you want to use more than two methods to configure the parameters in JDBC, the methods are prioritized in the following order: JDBC properties > configuration file > URL parameter.

You can concatenate multiple parameters using &.

Option 1: JDBC properties

Set MEK and ENC_ALGO directly in the Properties object before opening a connection:

// Replace the placeholders with your instance connection details.
String hostname = "<hostname>";
String port     = "<port>";
String dbname   = "<dbname>";
String username = "<username>";
String password = "<password>";

String mek     = "<your-mek>";   // 32-character hex string
String encAlgo = "<enc-algo>";   // e.g., 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);

Option 2: Configuration file

Create a configuration file with the following content:

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

Place the file in one of these locations:

  • The resources directory of your project

  • The root directory of your project (the working directory at runtime)

The default filename is encjdbc.conf. To use a custom path, set the encJdbcConfigFile system property to the directory of the configuration file.

After placing the file, connect without specifying MEK or ENC_ALGO in code:

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

Append MEK and ENC_ALGO directly to the 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);

Complete example

The following example uses JDBC properties to connect, insert rows into a table, and query the plaintext results.

// Replace the placeholders with your instance connection details.
String hostname = "hostname";
String port     = "port";
String dbname   = "db";
String username = "user";
String password = "password";

// Use a strong, randomly generated MEK in production.
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"};

// Create the table.
connection.createStatement().executeUpdate("drop table if exists test");
connection.createStatement().executeUpdate("create table test (a int, b text)");

// Insert rows using PreparedStatement.
// EncJDBC automatically encrypts values targeting encrypted columns.
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();
}

// Query rows. EncJDBC automatically decrypts results before returning them.
ResultSet rs = connection.createStatement().executeQuery("select * from test");
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");
}

Expected output:

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

Note the following:

  • All reads and writes to encrypted columns go through PreparedStatement. The driver automatically encrypts parameters and decrypts results—no changes to your query logic are required.

  • Values passed to non-encrypted columns are not affected.

Troubleshooting

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

This error occurs because newer JDK versions restrict cross-module access by default. Add the following VM option when running your program:

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

failed in mek provision: gcmEncrypt error

This is a known issue with Oracle JDK. Use one of the following fixes:

  • Switch to Amazon Corretto — a drop-in OpenJDK distribution that does not have this issue.

  • Add the BouncyCastle security provider to Oracle JDK:

    1. Locate your JDK installation directory.

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

    3. In the List of providers and their preference orders section, add: `` security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider ``