All Products
Search
Document Center

Database Autonomy Service:Integrate the Go driver for column encryption

Last Updated:Mar 28, 2026

alibabacloud-encdb-mysql-go-client is a Go driver for client-side column encryption. It intercepts query results and automatically decrypts ciphertext, so your application reads sensitive columns as plaintext without modifying your SQL queries. To enable decryption, specify your master encryption key (MEK) in the connection URL.

Prerequisites

Before you begin, ensure that you have:

  • Run a sensitive data detection scan to identify the 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 database account. For more information, see Column encryption.

  • The following connection details for the RDS instance with the always-confidential database feature enabled: host, port, database name, username, and password.

How it works

The driver connects to the database using your MEK as the root decryption credential. On connection, the client and server perform an asymmetric key exchange to establish a shared symmetric session key. All subsequent data is transmitted using symmetric encryption.

Integrate the driver

Step 1: Install the driver

alibabacloud-encdb-mysql-go-client is compatible with Go-MySQL-Driver and implements the standard database/sql/driver interface, so no SQL changes are required. Go 1.18 or later is required.

Run the following command to install the driver:

go get github.com/aliyun/alibabacloud-encdb-mysql-go-client@latest

The source code is available at alibabacloud-encdb-mysql-go-client on GitHub.

Step 2: Generate an MEK

The MEK must be a 32-character hexadecimal string (16 bytes). The always-confidential database feature does not generate, store, or back up your MEK — you are responsible for generating and storing it securely.

Generate a random MEK using OpenSSL:

  • Linux or macOS (built-in OpenSSL):

    openssl rand -hex 16
  • Windows: Install OpenSSL for Windows, then run the same command.

The command outputs a 32-character string such as 00112233445566778899aabbccddeeff.

Warning

An MEK is the root credential that you use to authorize a client to access encrypted data. To ensure security, the always-confidential database feature does not generate, store, or back up your MEK. You must manually generate an MEK and make sure that the MEK is securely stored. To ensure the security of databases for which the always-confidential database feature is enabled, you must store and manage the MEK in a secure manner. We recommend that you back up your MEK.

Step 3: Connect to the database

The driver registers itself under the name encmysql. Open a connection using sql.Open with encmysql as the driver name, and append MEK=<your-mek> to the connection URL.

Connection URL format:

<username>:<password>@tcp(<host>:<port>)/<dbname>?MEK=<mek-value>
PlaceholderDescription
<username>Database username
<password>Database password
<host>Endpoint (hostname) of the RDS instance
<port>Port number
<dbname>Database name
<mek-value>32-character hexadecimal MEK

Use & to append additional driver parameters: ?MEK=<value>&<param>=<value>.

The MEK is transmitted to the server using envelope encryption. Do not log or expose the MEK value in error messages or application output.

Example:

db, err := sql.Open("encmysql", "<username>:<password>@tcp(<hostname>:<port>)/<dbname>?MEK=00112233445566778899aabbccddeeff")
if err != nil {
    panic(err)
}

Step 4: Query encrypted columns

After connecting, query encrypted columns using standard database/sql calls. The driver decrypts the results transparently.

// Run a SELECT query against a table with encrypted columns.
rows, err := db.Query("SELECT * FROM sddp_test_mask")
if err != nil {
    log.Fatalf("Failed to query data: %v", err)
}
// Always close the result set when done.
defer rows.Close()

var id int
var name string
var password string
var age int

for rows.Next() {
    err := rows.Scan(&id, &name, &password, &age)
    if err != nil {
        log.Fatalf("Failed to scan row: %v", err)
    }
    fmt.Printf("read data: id=%d, name=%s, password=%s, age=%d\n", id, name, password, age)
}

Complete example

The following example connects to a PolarDB for MySQL database using an account with the ciphertext permission (JDBC decryption) and reads the plaintext values of encrypted columns.

For details about the column encryption configuration used here, see the Column encryption in a PolarDB for MySQL database section in Column encryption.

package main

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/aliyun/alibabacloud-encdb-mysql-go-client"
)

func main() {
    // Replace the placeholders with your actual connection details.
    db, err := sql.Open("encmysql", "sddp_02:He******4@tcp(polar***.rwlb.rds.aliyuncs.com:3306)/sddp_test?MEK=00112233445566778899aabbccddeeff")
    if err != nil {
        panic(err)
    }

    rows, err := db.Query("SELECT * FROM user3 LIMIT 3")
    if err != nil {
        log.Fatalf("Failed to query data: %v", err)
    }

    // Always close the result set when done.
    defer rows.Close()

    var id int
    var name string
    var password string
    var age int

    for rows.Next() {
        err := rows.Scan(&id, &name, &password, &age)
        if err != nil {
            log.Fatalf("Failed to scan row: %v", err)
        }
        fmt.Printf("read data: id=%d, name=%s, password=%s, age=%d\n", id, name, password, age)
    }
}

After the preceding code is called, the decrypted result similar to the following information is returned.

image

Related topics