All Products
Search
Document Center

PolarDB:Integrate EncJDBC

Last Updated:Apr 10, 2024

Confidential database encrypts data in query results. EncJDBC is a MySQL Java Database Connectivity (JDBC) for the always-confidential feature. EncJDBC is provided to deliver the always-confidential feature without the need for code modification in your Java systems. EncJDBC can automatically decrypt ciphertext data and return plaintext data to your application. This process is transparent to the application. You can connect to an instance with the always-confidential feature enabled from the application by performing minor configuration changes, and you do not need to modify the code of the application. This topic describes how to use EncJDBC to access an instance.

Prerequisites

  • The always-confidential feature is enabled. For more information, see Enable PolarDB Always-confidential.

  • The connection information about the instance for which the always-confidential feature is enabled is obtained. The connection information includes the domain name (host), port number (port), instance name (dbname), username (username), and password (password).

  • A data protection rule is configured. For more information, see Manage encryption rules.

Usage notes

  • You must store your master encryption key (MEK) and keep it confidential.

  • The Java version must be 1.8 or later.

Note

In this topic, the version of Maven is 3.9.2, and the development tool is IntelliJ IDEA Community Edition 2022.3.2.

Procedure

Step 1: Add Maven dependencies

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

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-encdb-mysql-jdbc</artifactId>
    <version>1.0.8</version>
</dependency>
Note

Replace the version value based on your environment when you add Maven dependencies. You can view the latest version of aliyun-encdb-mysql-jdbc on the official website.

Step 2: Configure EncJDBC based on sample code

You can use EncJDBC in the same manner as Java Database Connectivity (JDBC). Before you use EncJDBC, you must configure the required parameters, such as MEK and ENC_ALGO, in EncJDBC for data security. MEK specifies a master encryption key, and ENC_ALGO specifies an encryption algorithm. The following table describes the parameters:

Parameter

Description

Example (string type)

MEK

The MEK that is specified by the data owner.

MEK generation: You can use password generation tools such as OpenSSL and openssl rand -hex 16, call the random function in a programming language, or obtain keys from Key Management Service (KMS).

Valid value: a 16-byte hexadecimal string that is 32 characters in length.

Warning

An MEK is the root credential that you use to access encrypted data. For security purposes, the instance for which the always-confidential feature is enabled does not generate, store, or back up your MEK. You must generate an MEK and keep it confidential. If you lose your MEK, you can no longer access the data that is encrypted by using the MEK. Therefore, we recommend that you back up your MEK.

00112233445566778899aabbccddeeff

ENC_ALGO

The encryption algorithms that are used to protect the data. Valid values:

  • SM4_128_CBC (default)

  • SM4_128_ECB (not recommended)

  • SM4_128_GCM

  • SM4_128_CTR

  • AES_128_GCM

  • AES_128_ECB (not recommended)

  • AES_128_CBC

  • AES_128_CTR

SM4_128_CBC

Configure MEK and ENC_ALGO

The following section describes the methods that you can use to configure the MEK and ENC_ALGO parameters. 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, configuration file, and URL configuration.

Note
  • You can use ampersands (&) to concatenate multiple parameters.

  • In these methods, MEK is configured on the client side and transmitted to the server by using envelope encryption to ensure the confidentiality of the value of MEK.

JDBC properties

You can configure the key and algorithm as properties in EncJDBC. The following example shows how to configure the properties and use EncJDBC to perform database operations.

// Obtain the connection information such as the domain name (hostname), port number (port), instance name (dbname), username (username), and password (password).
// ...

String mek=...;
String encAlgo=...;

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

// ... Initiate a query ...

Configuration file

PolarDB for MySQL allows you to create a configuration file and configure the required parameters such as MEK in the configure file. Then, specify a property named encJdbcConfigFile in the project and set the value of the property to the directory of the configuration file. If you do not specify any directory, the system uses the encjdbc.conf file. Content of the configuration file:

MEK=
ENC_ALGO=

You can specify the directory of the configuration file by using the following methods.

  • Store the configuration file in the resources directory of the project as shown in the following figure:

    image.png

  • Store the configuration file in the root directory of the project. The root directory is the directory that is used by the application at runtime.

After the file configuration is complete, you do not need to configure additional settings in the application. See the following sample code:

// Obtain the connection information such as the domain name (hostname), port number (port), instance name (dbname), username (username), and password (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);

// ... Initiate a query ...

URL

PolarDB for MySQL allows you to configure the MEK and ENC_ALGO parameters in an URL. See the following sample code:

// Obtain the connection information such as the domain name (hostname), port number (port), instance name (dbname), username (username), and password (password).
// ...

String mek=...;
String encAlgo=...;

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

// ... Initiate a query ...

Complete sample code of JDBC properties configuration

// Update the connection information such as the domain name (hostname), port number (port), instance name (dbname), username (username), and password (password) to your instance information.
String hostname = "hostname";
String port = "port";
String dbname = "db";
String username = "user";
String password = "password";

String mek="00112233445566778899aabbccddeeff"; // This is an example value. We recommend that you use a more complex MEK.
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 table
connection.createStatement().executeUpdate("drop table if exists test");
connection.createStatement().executeUpdate("create table test (a int, b text)");

// insert data
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();
}

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

The following result is returned:

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

FAQ

  • What do I do if the Exception in thread "main" java.lang.IllegalAccessError: class com.alibaba.encdb.common.SymCrypto (in unnamed module @0x5c0369c4) cannot access class com.sun.crypto.provider.SunJCE (in module java.base) because module java.base does not export com.sun.crypto.provider to unnamed module @0x5c0369c4 error message is displayed when I run a program?

    The error message may be displayed due to the inter-module permission issues that occur when the JDK version is later than the required version. To resolve the error, you must add the VM option --add-exports=java.base/com.sun.crypto.provider=ALL-UNNAMED when you run the program to export com.sun.crypto.provider to the Unnamed module.

  • What do I do if the failed in mek provision: you might have an incorrect mek setting. Detail:gcmEncrypt error error message is displayed when I run a program?

    The error is a common error in Oracle JDK. To resolve the error, you can use one of the following methods:

    • Use Amazon Corretto instead.

    • If you use Oracle JDK, you must perform the following steps to configure a security provider:

      1. Find the JDK installation path.

      2. In the <Installation path>/conf/security/ directory, find the java.security file.

      3. Edit the java.security file. In the List of providers and their preference orders (see above): section, add the following content:

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