All Products
Search
Document Center

Data Security Center:Integrate EncJDBC

Last Updated:Nov 17, 2025

After you encrypt sensitive data columns in a table of an ApsaraDB RDS for MySQL, ApsaraDB RDS for PostgreSQL, PolarDB for MySQL, or PolarDB for PostgreSQL database, you can use the EncJDBC driver to connect to the database from a Java application and access the plaintext data in these encrypted columns. This topic describes how to use EncJDBC to connect to a database and access plaintext data in encrypted columns.

Prerequisites

  • Column encryption is configured for the target database, and the target database account is granted the Ciphertext Permission (JDBC Decryption) permission. For more information about how to configure column encryption for a database and for a detailed description of account permissions, see Configure column encryption for databases.

  • You have obtained the connection information for the encrypted database, including the endpoint, port, database name, database account, and password.

Background information

The column encryption feature lets you encrypt specific columns in a database to improve data security. Encrypted data is stored as ciphertext in the database. However, an authorized client can transparently decrypt the ciphertext and access the plaintext data.

Alibaba Cloud provides the always-encrypted client driver EncJDBC for the Java programming language. You can use the driver on the client to connect to the database and specify the Master Encryption Key (MEK) in the database connection URL to access the encrypted database. The driver automatically decrypts the ciphertext and returns plaintext data.

Generate an MEK

The client transmits the MEK to the database server over a secure asymmetric key encryption protocol. This process ensures that both the server and client share the same key, which enables secure data transmission using symmetric encryption.

Value range: A 16-byte hexadecimal string, which is 32 characters long.

Warning

The MEK is the root credential that authorizes a client to access encrypted data. For security reasons, the encrypted database does not hold or manage your MEK. It also does not provide services to generate or back up the MEK. You must generate the MEK yourself. Storing and managing the MEK is critical to database security. We recommend that you back up your MEK securely.

Depending on the Encryption Method selected in the column encryption configuration, you can obtain a KMS Key or generate a Local Key to use as the MEK for decrypting the database.

KMS key

Important

When you use a KMS key, ensure that Key Management Service (KMS) is available. Otherwise, the always-encrypted client driver EncJDBC will not function.

You need to obtain the endpoint of the KMS instance that contains the selected KMS key from the column encryption configuration. You also need the AccessKey ID and AccessKey secret of the corresponding Alibaba Cloud account or Resource Access Management (RAM) user. This account or user must have KMS decryption permissions to allow the client to read the KMS key. Perform the following steps:

  1. Log on to the console using an Alibaba Cloud account or a RAM user.

  2. If you are a RAM user, grant the RAM user KMS decryption permissions.

    1. Create a custom permission policy. The policy content is as follows:

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

  3. Obtain the KMS instance endpoint.

    • By default, keys in a KMS instance can be accessed only from a VPC network. On the instance management page of KMS, find the target KMS instance, click Details in the Actions column, and then view the instance VPC endpoint on the Basic Information tab.

    • To access the key over the Internet, enable public network access and then view the Public Endpoint. For more information, see Enable public network access.

  4. Obtain an AccessKey pair.

    When you create an AccessKey pair for an Alibaba Cloud account or a RAM user, save the AccessKey ID and AccessKey secret. For more information, see Create an AccessKey pair.

Local key

When the Encryption Method in the column encryption configuration is set to Local Key, you need to generate an MEK. For example, 00112233445566778899aabbccddeeff.

Common generation methods include using a password generation tool or a random function in a programming language.

For example:

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

  • On Windows, you can install the OpenSSL software package.

Client access instructions

Important

Use Java Development Kit (JDK) 1.8 or later.

On the client, you can change the database connection driver to EncJDBC, update the database connection URL, and specify the MEK to access the plaintext data in encrypted columns.

1. 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>

2. Configure the MEK to connect to the database

You can use the following methods to configure the MEK: JDBC properties configuration, file configuration, and URL configuration. If you configure your Java Database Connectivity (JDBC) using more than one method, the following priority applies: JDBC properties configuration > File configuration > URL configuration.

Note
  • In the URL configuration method, you can concatenate multiple parameters with an ampersand (&).

  • With the following configuration and connection methods, the MEK is processed locally on the client and sent to the server securely using envelope encryption. This ensures that the MEK is not leaked.

Based on the Encryption Method in the column encryption configuration, connect to the database using either a local key or a KMS key.

Connect to the database using a KMS key

Important
  • If you use a temporary access credential from the Security Token Service (STS) to obtain the KMS-managed MEK, you can use an STS software development kit (SDK) to obtain a temporary STS token. For STS SDK examples, see STS SDK overview.

  • Do not hard-code the AccessKey pair (AccessKey ID and AccessKey secret) 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.

JDBC properties configuration

When you connect using standard JDBC, you can set custom user properties through Properties. The following example shows how to configure and run JDBC in this way:

// Prepare the 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 system environment variables.
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// If you use an STS temporary access credential to read the KMS key, you also need to provide the obtained Security Token Service (STS) token.
// String stsToken= "yourSecurityToken";

// The endpoint of the KMS instance. Use the public endpoint for Internet access. Use the instance VPC endpoint for VPC 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");



// The following is the connection URL format for an RDS for 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 an RDS for 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, as shown in the following example:

// Prepare the 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 system environment variables.
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// If you use an STS temporary access credential to read the KMS key, you also need to provide the obtained STS token.
// String stsToken= "yourSecurityToken";

// The endpoint of the KMS instance. Use the public endpoint for Internet access. Use the instance VPC endpoint for VPC access.
String kmsEndpoint = "kms.cn-hangzhou.aliyuncs.com";

// The following is the connection URL format for an RDS for 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 an RDS for MySQL database.
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

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

// ... Initiate a query ...

Connect to the database using a local key

JDBC properties configuration

When you connect using standard JDBC, you can set custom user properties through Properties. The following example shows how to configure and run JDBC in this way:

// Prepare the 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 following is the connection URL format for an RDS for MySQL database: "jdbc:mysql:encdb://%s:%s/%s". For an RDS for PostgreSQL database, replace the format with "jdbc:postgresql:encdb://%s:%s/%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);

// The following loads the EncJDBC driver for an RDS for MySQL database. For an RDS for PostgreSQL database, replace the driver with "com.aliyun.encdb.postgresql.jdbc.EncDriver".
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

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

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

You can import parameters, such as the required MEK, from a configuration file.

Note

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

In your project, you can set a property named encJdbcConfigFile and set its value to the path of the configuration file. If you do not set this property, the encjdbc.conf file is used by default. The content of the configuration file is as follows:

MEK=00112233445566778899aabbccddeeff

You can place the configuration file in one of the following two locations:

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

    image

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

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

// Prepare the 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 following is the connection URL format for an RDS for MySQL database: "jdbc:mysql:encdb://%s:%s/%s". For an RDS for PostgreSQL database, replace the format with "jdbc:postgresql:encdb://%s:%s/%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);

// The following loads the EncJDBC driver for an RDS for MySQL database. For an RDS for PostgreSQL database, replace the driver with "com.aliyun.encdb.postgresql.jdbc.EncDriver".
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, as shown in the following example:

// Prepare the 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 following is the connection URL format for an RDS for MySQL database: "jdbc:mysql:encdb://%s:%s/%s?MEK=%s". For an RDS for PostgreSQL database, replace the format with "jdbc:postgresql:encdb://%s:%s/%s?MEK=%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?MEK=%s", hostname, port, dbname, mek);

// The following loads the EncJDBC driver for an RDS for MySQL database. For an RDS for PostgreSQL database, replace the driver with "com.aliyun.encdb.postgresql.jdbc.EncDriver".
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");

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

// ... Initiate a query ...

3. Query the plaintext data of encrypted columns

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

Sample code:

// Initiate a query.

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

Complete code example

This section provides an example of using the JDBC properties configuration to set a local key MEK. It shows how to use a database account with the Ciphertext Permission (JDBC Decryption) permission to query the plaintext data in encrypted columns in an RDS for MySQL database.

For information about the database configuration in the following example, see the RDS MySQL database column encryption example in Verify column encryption results.

Note

This example uses Maven 3.9.9 and the development tool 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 {
        // Replace the following connection information, such as the endpoint (hostname), port, database instance name (dbname), username, and password, with your instance information.
        String hostname = "rm-******.mysql.rds.aliyuncs.com";
        String port = "3306";
        String dbname = "sddp_em_db";
        String username = "sddp_em03";
        String password = "******";
        
        // This is only an example. We recommend that you use a more complex key.
        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);

        // 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 the resources.
            resultSet.close();
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Sample output:

image