如果您希望使用全密態功能對資料庫表中的被保護資料列進行加密,並且使用Go應用程式訪問資料庫,可以使用全密態用戶端驅動程式alibabacloud-encdb-mysql-go-client接入全密態資料庫。本文介紹如何通過Go驅動訪問全密態資料庫。
在持有使用者密鑰的情況下,alibabacloud-encdb-mysql-go-client能夠自動完成密文資料的解密並返回明文資料,過程對應用透明,應用程式只需配置幾行代碼就可以接入全密態資料庫,降低了使用全密態功能的成本。
前提條件
已開通全密態PolarMySQL功能,並按照實際需求配置了加密規則。開通全密態PolarMySQL功能的具體操作步驟請參見如何開通全密態PolarMySQL功能。
已擷取加密資料庫的串連資訊。如網域名稱(host)、連接埠(port)、資料庫名(dbname)、使用者名稱(username)和密碼(password)等。
已部署Go程式,且Go版本需為1.18或以上。
操作步驟
擷取全密態資料庫Go驅動
go get github.com/aliyun/alibabacloud-encdb-mysql-go-client@latestalibabacloud-encdb-mysql-go-client全面相容社區版的GoLang MySQL Driver,支援標準GoLang的database/sql/driver介面,業務側可實現零改造接入。
驅動已開源在GitHub,請參見https://github.com/aliyun/alibabacloud-encdb-mysql-go-client。
通過全密態用戶端查詢資料
您可以像使用GoLang MySQL Driver一樣使用alibabacloud-encdb-mysql-go-client,但需要預先配置MEK(主要金鑰)和ENC_ALGO(密碼編譯演算法)參數。PolarDB支援在URL連結中嵌入參數,方法如下:
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 | 使用者主要金鑰,由使用者自訂指定。 常見的產生方法:密碼產生工具(如openssl、openssl rand -hex 16)、程式設計語言中的random函數或者從第三方Key Management Service(KMS)擷取。 取值範圍:長度為16個位元組的十六進位字串,且總長度為32個字元。 重要 使用者主要金鑰是訪問加密資料的根憑據,出於安全考慮,全密態資料庫不持有並系統管理使用者的主要金鑰,也不提供使用者主要金鑰的產生和備份服務,您需要自行產生使用者主要金鑰。一旦您丟失密鑰,將無法再訪問已有的資料。因此,建議您妥善備份使用者主要金鑰。 | 00112233445566778899aabbccddeeff |
ENC_ALGO | 被保護資料使用的密碼編譯演算法。目前支援AES(國際演算法)和
說明 AES_128_ECB和SM4_128_ECB密碼編譯演算法安全性較弱,請謹慎使用。 | SM4_128_CBC |
樣本
該樣本以建立demo專案go mod init demo為例,來介紹使用alibabacloud-encdb-mysql-go-client的方法。
package main
import (
"database/sql"
"fmt"
_ "github.com/aliyun/alibabacloud-encdb-mysql-go-client"
)
func main() {
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)
}實際執行過程中,請將樣本中的網域名稱(hostname)、連接埠(port)、資料庫名(dbname)、使用者名稱(username)和密碼(password)等串連資訊更換為實際的叢集資訊。調用上述代碼後,系統返回類似如下解密後的結果資訊:
read data: 0 test 0.000000