All Products
Search
Document Center

PolarDB:Integrate EncJDBC

Last Updated:Jan 14, 2026

The Confidential database feature provides a dedicated client driver, Encrypted Java Database Connectivity (EncJDBC), to enable seamless integration with your Java applications without requiring code modifications. EncJDBC automatically decrypts ciphertext and returns plaintext data. This process is transparent to the application. Your application can connect to the Confidential database feature with just a few lines of configuration, and no changes to your existing business code are required.

Solution architecture

The Confidential database feature is a dynamic encryption and decryption solution based on a database proxy. The proxy layer encrypts pre-configured sensitive fields in query results before returning them to the client. The client application must use the dedicated EncJDBC driver to transparently decrypt the data upon receipt.

Workflow and role permissions:

  1. Query request: The client application sends a standard SQL query to the PolarDB cluster endpoint through the EncJDBC driver.

  2. Proxy processing: The database proxy receives the request and forwards it to the backend database kernel for execution.

  3. On-the-fly encryption: As query results are returned, the proxy layer checks whether they match a predefined encryption policy. If a match is found, the sensitive fields in the result set are encrypted using a specified key from KMS or a self-managed key.

  4. Data return: The encrypted result set is returned to the client.

  5. Transparent decryption: The EncJDBC driver on the client automatically decrypts the ciphertext. The application receives plaintext data, and the entire process is transparent to your business code.

Query results vary based on the role of the database account:

  • Super administrator: Query results are always in plaintext and are not affected by encryption policies. This is useful for database management and auditing.

  • Regular user: Query results are returned as ciphertext. You must use the EncJDBC driver and the correct key to decrypt the data on the client.

  • Other users: Query results are returned as ciphertext and cannot be decrypted.

Limits

Before you implement this feature, review the following limits to assess whether the feature meets your business and technical architecture requirements.

  • Endpoint requirement: Encryption rules take effect only when you connect using a cluster endpoint or a custom endpoint. Connecting directly to the primary endpoint bypasses the proxy, which disables the encryption feature.

  • Key management: When you use a self-managed key, key rotation is not supported. You also risk key loss or leakage. If a key is lost, the corresponding encrypted data cannot be decrypted. You must establish strict security procedures to manage your keys.

  • JDK version: You must use JDK 1.8 or later.

Use a KMS key

Step 1: Configure KMS access permissions

  1. Obtain an AccessKey pair: Obtain the AccessKeyId and AccessKeySecret of a RAM user. This allows the application to obtain the master encryption key (MEK) that is managed by KMS.

    1. If you already have a suitable RAM user to access KMS, you can use that user.

    2. If you do not have a suitable RAM user, go to the RAM console. In the navigation pane on the left, choose Identity Management > Users. Click Create User and follow the on-screen instructions to create a user.

  2. Grant permissions to the RAM user:

    1. Go to the RAM console. In the navigation pane on the left, choose Permission Management > Access Policies. Click Create Access Policy. Switch to the script editor, copy the following content, and click OK. Enter a policy name and complete the creation.

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "KMS:Decrypt",
                  "Resource": "*"
              }
          ]
      }
    2. Return to the RAM console. In the navigation pane on the left, choose Identity Management > Users. Find the target RAM user. In the Actions column, click Add Permissions. Grant the newly created access policy to the user. This allows PolarDB to dynamically decrypt data.

  3. Obtain the KMS instance endpoint:

    • VPC endpoint (default): By default, keys in a KMS instance can be accessed only from within a VPC. You can go to the KMS instance management page, select the region where the instance is located, find the target KMS instance, and click Details in the Actions column. Then, on the Basic Information tab, you can view the instance VPC endpoint.

    • Public endpoint: To access the key over the Internet, you must enable public network access on the RD Multi-Account tab. After you enable public access, you can view the Public Endpoint on the Basic Information tab.

Step 2: Install dependencies

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

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

When you add the Maven dependency, replace the value of version as needed. You can find the latest version of aliyun-cls-jdbc on the official website.

Step 3: Configure the MEK to connect to the database

You can configure the MEK using JDBC properties, a file, or a URL. If you configure your JDBC using two or more methods, the priority is as follows: JDBC properties configuration > File configuration > URL configuration.

Note
  • In the following configuration and connection methods, the MEK is processed locally on the client and sent to the server using a secure method (envelope encryption) to ensure that the MEK is not leaked.

  • Do not hard-code the AccessKey pair (AccessKeyId and AccessKeySecret) in your business code. This example uses system environment variables to manage the AccessKey pair. For more information, see Configure environment variables on Linux, macOS, and Windows systems.

  • To use a temporary access credential to obtain the KMS-managed MEK, you can use an STS SDK to obtain a temporary credential, the Security Token Service (STS) token. For STS SDK examples, see Overview of STS SDKs.

JDBC properties configuration

When a standard JDBC connection is established, you can set custom attributes using a Properties object.

Example

// Prepare connection information such as the endpoint (hostname), port, database instance name (dbname), username, and password.
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";

// Get the AccessKey ID and AccessKey secret from environment variables.
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// If you use a temporary STS access credential to read the KMS key, you also need to fill in the obtained Security Token Service token (SecurityToken).
// String stsToken= "yourSecurityToken";

// For the KMS instance endpoint, use the public endpoint for public network access. Use the instance VPC endpoint for access within a VPC.
String kmsEndpoint = "your-kms-endpoint";

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

// The following is the connection URL format for a MySQL database: "jdbc:mysql:encdb://%s:%s/%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);

// The following loads the EncJDBC driver for a MySQL database.
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, props);

// ... Initiate a query ...
URL configuration

You can embed the parameters for obtaining the KMS key in the URL.

Example

// Prepare connection information such as the endpoint (hostname), port, database instance name (dbname), username, and password.
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";

// Get the AccessKey ID and AccessKey secret from environment variables.
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// If you use a temporary STS access credential to read the KMS key, you also need to fill in the obtained Security Token Service token (SecurityToken).
// String stsToken= "yourSecurityToken";

// For the KMS instance endpoint, use the public endpoint for public network access. Use the instance VPC endpoint for access within a VPC.
String kmsEndpoint = "your-kms-endpoint";

// The following is the connection URL format for a MySQL database.
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);
// Use an STS token.
// 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);

// The following loads the EncJDBC driver for a MySQL database.
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, username, password);

// ... Initiate a query ...

Step 4: Query plaintext data from encrypted columns

After you successfully connect to the database, you can perform database operations as you would with a regular JDBC query. EncJDBC automatically decrypts encrypted columns and returns plaintext data.

Example

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

// Traverse the result set.
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");
}

Appendix: Complete code example

Note

This example uses Maven version 3.9.9 and the IntelliJ IDEA Community Edition 2024.1.2 development tool.

import java.sql.*;
import java.util.Properties;

public class EncryptedColumnAccess {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // Update the following connection information with your instance details, such as endpoint (hostname), port, database instance name (dbname), username, and password.
        String hostname = "your-hostname";
        String port = "your-port";
        String dbname = "your-database-name";
        String username = "your-username";
        String password = "your-password";

        // Get the AccessKey ID and AccessKey secret from environment variables.
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        // If you use a temporary STS access credential to read the KMS key, you also need to fill in the obtained Security Token Service token (SecurityToken).
        // String stsToken= "yourSecurityToken";

        // For the KMS instance endpoint, use the public endpoint for public network access. Use the instance VPC endpoint for access within a VPC.
        String kmsEndpoint = "your-kms-endpoint";

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

        // The connection URL format for a MySQL database is "jdbc:mysql:encdb://%s:%s/%s".
        String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);

        // Load the EncJDBC driver.
        Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

        // Get the database connection.
        Connection connection = DriverManager.getConnection(dbUrl, props);

        // Initiate a query.
        try {
            // Create a query statement.
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("SELECT * FROM users");

            // Traverse the result set.
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("username");
                String phone = resultSet.getString("phone");

                // Process other fields based on your table schema.
                System.out.println("ID: " + id + ", Name: " + name + ", Phone: " + phone);
            }

            // Close resources.
            resultSet.close();
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Use a local key

Step 1: Generate an MEK

Warning

The MEK is the root credential that you use to authorize clients to access encrypted data. For security reasons, the encrypted database does not store or manage your MEK. It also does not provide MEK generation or backup services. You are responsible for generating the MEK. Storing and managing the MEK is critical to database security. Therefore, we recommend that you back up your MEK securely.

MEK: The MEK is transmitted from the client to the database server using a secure asymmetric key encryption protocol. This allows the server and client to share the same key for secure data transmission through symmetric encryption.

Valid value: a 16-byte hexadecimal string that is 32 characters in length. For example, 00112233445566778899aabbccddeeff.

Common generation methods: You can use password generation tools or the random function in a programming language.

Example

  • On Linux, you can use the built-in OpenSSL tool. Run openssl rand -hex 16 to generate a key.

    # Use OpenSSL to generate a secure random key
    openssl rand -hex 16
    # Example output: 11ce9a9489fab7355cf710837cea5d5b
  • On Windows, you can install the OpenSSL package.

Step 2: Install dependencies

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

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

When you add the Maven dependency, replace the value of version as needed. You can find the latest version of aliyun-cls-jdbc on the official website.

Step 3: Configure the MEK to connect to the database

You can configure the MEK using JDBC properties, a file, or a URL. If you configure your JDBC using two or more methods, the priority is as follows: JDBC properties configuration > File configuration > URL configuration.

Note

In the following configuration and connection methods, the MEK is processed locally on the client and sent to the server using a secure method (envelope encryption) to ensure that the MEK is not leaked.

JDBC properties configuration

When a standard JDBC connection is established, you can set custom attributes using a Properties object.

Example

// Prepare connection information such as the endpoint (hostname), port, database instance name (dbname), username, and password.
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";

// Customer master key.
String mek = "00112233445566778899aabbccddeeff"; 

Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);

// The connection URL format for a MySQL database is "jdbc:mysql:encdb://%s:%s/%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);

// Load the EncJDBC driver for a MySQL database.
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, props);

// ... Initiate a query ...
File configuration
Note

The file configuration method is applicable only to configuring a local MEK.

You can import parameters, such as the required MEK, from a configuration file. In your project, set a property named encJdbcConfigFile and set its value to the path of the configuration file. If you do not specify a path, the system uses the encjdbc.conf file by default. The following code shows the content of the configuration file:

MEK=00112233445566778899aabbccddeeff

Example

  1. You can specify the location of the configuration file in one of the following two ways:

    • Place the file in the resources directory of your project, as shown in the following figure:

      image

    • Place the file in the root directory of the project, which is the runtime directory of the program.

  2. After you configure the file, you do not need to make additional configurations in your program, as shown in the following code:

    // Prepare connection information such as the endpoint (hostname), port, database instance name (dbname), username, and password.
    String hostname = "your-hostname";
    String port = "your-port";
    String dbname = "your-database-name";
    String username = "your-username";
    String password = "your-password";
    
    // The connection URL format for a MySQL database is "jdbc:mysql:encdb://%s:%s/%s".
    String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
    
    // Load the EncJDBC driver for a MySQL database.
    Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
    
    // Get the database connection.
    Connection connection = DriverManager.getConnection(dbUrl, username, password);
    
    // ... Initiate a query ...
URL configuration

You can embed parameters, such as the MEK, in the URL.

Example

// Prepare connection information such as the endpoint (hostname), port, database instance name (dbname), username, and password.
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";

 // Customer master key.
String mek = "00112233445566778899aabbccddeeff";

// The connection URL format for a MySQL database is "jdbc:mysql:encdb://%s:%s/%s?MEK=%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?MEK=%s", hostname, port, dbname, mek);

// Load the EncJDBC driver for a MySQL database.
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, username, password);

// ... Initiate a query ...

Step 4: Query plaintext data from encrypted columns

After you successfully connect to the database, you can perform database operations as you would with a regular JDBC query. EncJDBC automatically decrypts encrypted columns and returns plaintext data.

Example

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

// Traverse the result set.
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");
}

Appendix: Complete code example

Note

This example uses Maven version 3.9.9 and the IntelliJ IDEA Community Edition 2024.1.2 development tool.

import java.sql.*;
import java.util.Properties;

public class EncryptedColumnAccess {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // Update the following connection information with your instance details, such as endpoint (hostname), port, database instance name (dbname), username, and password.
        String hostname = "your-hostname";
        String port = "your-port";
        String dbname = "your-database-name";
        String username = "your-username";
        String password = "your-password";
        
        // This is just an example. Use a more complex key.
        String mek="00112233445566778899aabbccddeeff";

        Properties props = new Properties();
        props.setProperty("user", username);
        props.setProperty("password", password);
        props.setProperty("MEK", mek);
        
        // The connection URL format for a MySQL database is "jdbc:mysql:encdb://%s:%s/%s".
        String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);

        // Load the EncJDBC driver.
        Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

        // Get the database connection.
        Connection connection = DriverManager.getConnection(dbUrl, props);

        // Initiate a query.
        try {
            // Create a query statement.
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("SELECT * FROM users");

            // Traverse the result set.
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("username");
                String phone = resultSet.getString("phone");

                // Process other fields based on your table schema.
                System.out.println("ID: " + id + ", Name: " + name + ", Phone: " + phone);
            }

            // Close resources.
            resultSet.close();
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

FAQ

When I integrate EncJDBC, I receive the error Code: Forbidden.KeyNotFound; Message: code: 404, The specified Key is not found. What should I do?

Check whether the KMS instance endpoint is correctly set in your application.

  • Check the application environment: KMS instance endpoints are different for VPCs and public networks.

    • VPC endpoint (default): By default, keys in a KMS instance can be accessed only from within a VPC. You can go to the KMS instance management page, select the region where the instance is located, find the target KMS instance, and click Details in the Actions column. Then, on the Basic Information tab, you can view the instance VPC endpoint.

    • Public endpoint: To access the key over the Internet, you must enable public network access on the RD Multi-Account tab. After you enable public access, you can view the Public Endpoint on the Basic Information tab.

  • Check the KMS instance region:

    • Adjust the endpoint based on your KMS instance region. For example, the public endpoint for China (Hangzhou) should be kms.cn-hangzhou.aliyuncs.com, and the public endpoint for China (Beijing) should be kms.cn-beijing.aliyuncs.com.

When I integrate EncJDBC, I receive the error Code: UnsupportedOperation; Message: code: 400, This action is not supported. What should I do?

This error may occur for the following reasons. Review the following possible causes:

  • You might be using the master key of a default key instead of a KMS Customer Master Key.

    Note

    Your default master key can be used only for server-side encryption by cloud products. It cannot be used for your client-side data encryption. To encrypt data on the client side for the Confidential database feature, you must create an instance and purchase a software-based or hardware-based customer master key (CMK).

  • Public network access is not enabled for the KMS instance.

When I integrate EncJDBC, I receive the error Code: Forbidden.NoPermission; Message: code: 403, This operation for XXX is forbidden by permission system. What should I do?

Your AccessKey pair (AccessKeyId and AccessKeySecret) may not have the required permissions to access KMS. You must grant the KMS:Decrypt permission so that PolarDB can dynamically decrypt data.

  1. Go to the RAM console. In the navigation pane on the left, choose Permission Management > Access Policies. Click Create Access Policy. Switch to the script editor, copy the following content, and click OK. Enter a policy name and complete the creation.

    {
        "Version": "1",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "KMS:Decrypt",
                "Resource": "*"
            }
        ]
    }
  2. Return to the RAM console. In the navigation pane on the left, choose Identity Management > Users. Find the target RAM user. In the Actions column, click Add Permissions. Grant the newly created access policy to the user. This allows PolarDB to dynamically decrypt data.