GoLang驱动

更新时间:2025-03-19 03:44:38
重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

配置RDS MySQL版或PolarDB MySQL版数据库表中敏感数据列加密后,如果希望通过GO应用访问这些加密列的明文,可使用alibabacloud-encdb-mysql-go-client驱动连接数据库。本文介绍如何使用alibabacloud-encdb-mysql-go-client连接数据库并访问加密列的明文数据。

背景信息

列加密功能允许用户对数据库中的特定列进行加密存储,从而提高数据的安全性。加密后的数据在数据库中以密文形式存储,但通过授权的客户端可以透明地解密并访问明文数据。

阿里云提供了Go语言的全密态客户端驱动程序alibabacloud-encdb-mysql-go-client。用户只需在客户端侧使用该驱动连接数据库,并在数据库连接URL中指定主密钥(Master Encryption Key,简称MEK),即可访问加密数据库。该驱动会自动完成密文数据的解密返回明文数据。

MEK:由客户端通过安全的非对称加密协议传输给数据库服务端,使服务端、客户端具有相同的密钥,从而通过对称加密安全传输数据。

取值范围:长度为16字节的16进制字符串,且长度为32个字符。

警告

MEK是您授权客户端访问加密数据的根凭据。出于安全考虑,加密数据库不持有并管理您的MEK,也不提供MEK的生成和备份服务,您需要自行生成MEK。MEK的保存和管理对数据库的安全性非常重要。因此我们建议您妥善备份MEK。

前提条件

  • 已为目标数据库配置列加密能力,并设置目标数据库账号的密文权限为密文权限(JDBC解密)。配置数据库列加密的具体操作和账号权限的详细说明,请参见列加密

  • 已获取加密数据库连接信息:连接地址、端口、数据库名称、数据库账号、密码。

  • 已生成一个MEK,用32位的十六进制字符串表示。例如,00112233445566778899aabbccddeeff。

    常见的生成方法有:密码生成工具或编程语言中的random函数。

    例如:

    • Linux系统自带OpenSSL工具,执行openssl rand -hex 16,生成密钥。

    • Windows系统,请安装OpenSSL软件包

注意事项

  • 请妥善保存您设置的主密钥MEK

  • Go版本需要在1.18及以上。

客户端接入说明

1. 获取驱动程序

alibabacloud-encdb-mysql-go-client全面兼容社区版的GoLang MySQL Driver,支持标准GoLangdatabase/sql/driver接口,业务侧可实现零改造接入。

驱动已开源在GitHub,详细说明请参见alibabacloud-encdb-mysql-go-client

获取方法:

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

2. 配置MEK并连接数据库

说明
  • URL配置方式中,多个参数可以使用&进行拼接。

  • MEK在客户端本地进行处理,并以安全方式(信封加密)发送到服务端,保证MEK不泄露。

示例代码:

// 以下连接地址(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息需要更新为您的实例信息 
db, err := sql.Open("encmysql", "<username>:<password>@tcp(<hostname>:<port>)/<dbname>?MEK=00112233445566778899aabbccddeeff")
if err != nil {
    panic(err)
}

3. 查询加密列的明文数据

示例代码:

// 发起查询	
rows, err := db.Query("SELECT * FROM sddp_test_mask")
if err != nil {
    log.Fatalf("Failed to query data: %v", err)
}
// 确保查询结果集在使用后关闭
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)
}

完整代码示例

例如使用具备密文权限(JDBC解密)的数据库账号查询某PolarDB MySQL数据库中加密列的明文数据。

以下示例中数据库配置的相关信息,请参见验证列加密结果中的PolarDB MySQL数据库列加密示例

package main

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

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

func main() {
    // 以下连接地址(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息需要更新为您的实例信息

    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)
    }
	
    // 确保查询结果集在使用后关闭
    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)
    }
}

调用上述代码后,系统会返回类似如下解密后的结果:

image

  • 本页导读
  • 背景信息
  • 前提条件
  • 注意事项
  • 客户端接入说明
  • 1. 获取驱动程序
  • 2. 配置MEK并连接数据库
  • 3. 查询加密列的明文数据
  • 完整代码示例