本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
如果您希望使用全密态功能对数据库表中的被保护数据列进行加密,并且使用Go应用程序访问数据库,可以使用全密态客户端驱动程序alibabacloud-encdb-mysql-go-client接入全密态数据库,接入操作便捷,能够降低使用全密态功能的成本。本文介绍如何通过alibabacloud-encdb-mysql-go-client访问全密态数据库。
在持有用户密钥的情况下,alibabacloud-encdb-mysql-go-client能够自动完成密文数据的解密并返回明文数据,过程对应用透明,应用程序只需配置几行代码就可以接入全密态数据库,降低了使用全密态功能的成本。
前提条件
注意事项
请妥善保存您设置的主密钥
MEK
。Go版本需要在1.18及以上。
操作步骤
步骤一:获取驱动程序
go get github.com/aliyun/alibabacloud-encdb-mysql-go-client@latest
alibabacloud-encdb-mysql-go-client
全面兼容社区版的GoLang MySQL Driver,支持标准GoLang的database/sql/driver接口,业务侧可实现零改造接入。驱动已开源在GitHub,请参见https://github.com/aliyun/alibabacloud-encdb-mysql-go-client。
步骤二:通过全密态客户端查询
URL配置
GoLang MySQL Driver的使用方式和
alibabacloud-encdb-mysql-go-client
基本一致,但需要预先在alibabacloud-encdb-mysql-go-client
中配置MEK
(主密钥)和ENC_ALGO
(加密算法)参数。我们支持在URL链接中嵌入参数,准备域名(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息后发起查询:mek := ... encAlgo := ... db, err := sql.Open("encmysql", "<username>:<password>@tcp(<hostname>:<port>)/<dbname>?MEK=<mek>&ENC_Algo=<encAlgo>") if err != nil { panic(err) }
说明URL配置方式中,多个参数可以使用
&
进行拼接。MEK
均在客户端本地进行处理,并以安全方式(信封加密)分发到服务端,始终保证MEK
不泄露。
MEK
和encAlgo
的含义及取值示例如下:参数
取值示例(字符串类型)
说明
MEK
00112233445566778899aabbccddeeff
用户主密钥,由用户自定义指定。
常见的生成方法有:密码生成工具(如openssl, openssl rand -hex 16)、编程语言中的random函数、或者从第三方密钥管理服务(KMS)获取。
取值范围:长度为16字节的16进制字符串,且长度为32个字符。
警告用户主密钥是您访问加密数据的根凭据,出于安全考虑,全密态数据库不持有并管理您的主密钥,也不提供用户主密钥的生成和备份服务,您需要自行生成用户主密钥。一旦您丢失密钥,将无法再访问已有的数据。因此我们建议您妥善备份用户主密钥。
ENC_ALGO
SM4_128_CBC
指明被保护数据将要使用的加密算法。
取值范围:
国际算法:
AES_128_GCM
AES_128_CTR
AES_128_CBC
AES_128_ECB(不推荐)
国密算法:
SM4_128_GCM(默认)
SM4_128_CTR
SM4_128_CBC
SM4_128_ECB(不推荐)
说明AES_128_ECB和SM4_128_ECB加密算法安全性较弱,请谨慎使用,推荐适用其他安全性更高的加密算法。
可选,默认为SM4_128_GCM。
完整代码示例
本文以新建demo项目(
go mod init demo
)为例用于代码示例。package main import ( "database/sql" "fmt" _ "github.com/aliyun/alibabacloud-encdb-mysql-go-client" ) func main() { // 以下域名(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息需要更新为您的实例信息 db, err := sql.Open("encmysql", "<username>:<password>@tcp(<hostname>:<port>)/<dbname>?MEK=00112233445566778899aabbccddeeff&ENC_ALGO=SM4_128_CBC") if err != nil { panic(err) } _, err = db.Exec("DROP TABLE IF EXISTS test") if err != nil { panic(err) } _, err = db.Exec(`create table test(a int, b text, c float)`) if err != nil { panic(err) } _, err = db.Exec(`insert into test set a = 0, b = 'test', c = 0.0`) if err != nil { panic(err) } rows, err := db.Query("SELECT * FROM test") rows.Next() var a int var b string var c float32 err = rows.Scan(&a, &b, &c) fmt.Printf("read data: %d %s %f\n", a, b, c) }
调用上述代码后,系统会返回类似如下解密后的结果:
read data: 0 test 0.000000