Alibaba Cloud は、クライアント側のデータベース暗号化を簡素化する専用の Go ドライバである alibabacloud-encdb-mysql-go-client を提供しています。これは暗号文の復号を自動化し、Go アプリケーションが機密データを通常のプレーンテキストのように透過的に、最小限のコード変更で処理できるようにします。これを有効にするには、ドライバを使用して接続し、接続 URL にマスター暗号化キー(MEK)を指定するだけです。このガイドでは、ドライバを統合し、接続を構成し、暗号化されたデータにクエリを実行するための手順を説明します。
前提条件
開始する前に、次の設定が完了していることを確認してください。
暗号化するカラムを特定するために、機密データ検出スキャンを実行しました。 詳細については、「機密データ検出」をご参照ください。
ターゲットデータベースの暗号化を有効にし、ターゲット [データベースアカウント] に [暗号文権限(JDBC 復号)] を付与しました。 詳細については、「カラム暗号化」をご参照ください。
Always-Confidential データベース機能が有効になっている RDS インスタンスの接続情報を取得します。 接続情報には、ドメイン名(host)、ポート番号(port)、インスタンス名(dbname)、ユーザー名(username)、およびパスワード(password)が含まれます。
マスター暗号化キー(MEK)
MEK は、クライアントアプリケーションが暗号化されたデータにアクセスすることを承認するルート資格情報です。 これは次のように機能します:
クライアントは、安全な非対称キー暗号化プロトコルを介してキーをデータベースサーバーに送信します。 このプロセスにより、サーバーとクライアントは同じキーを共有できるため、対称暗号化を使用してデータを安全に送信できます。
値は 32 文字の 16 進数文字列で、16 バイトのデータを表す必要があります。
MEK は、クライアントが暗号化されたデータにアクセスすることを承認するために使用するルート資格情報です。 セキュリティを確保するために、Always-Confidential データベース機能は MEK を生成、保存、またはバックアップしません。 MEK を手動で生成し、MEK が安全に保管されていることを確認する必要があります。 Always-Confidential データベース機能が有効になっているデータベースのセキュリティを確保するために、MEK を安全な方法で保存および管理する必要があります。 MEK をバックアップすることをお勧めします。
MEK の生成と安全な保管は、お客様の責任で行ってください。一般的な方法は、OpenSSL のような暗号化ツールを使用することです。
例:
Linux または macOS では、組み込みの OpenSSL ツールを使用して次のコマンドを実行します。
openssl rand -hex 16これは、ランダムな 32 文字の 16 進数文字列を生成します。例:
00112233445566778899aabbccddeeffWindows では、OpenSSL パッケージ をインストールして、同じコマンドを使用します。
使用上の注意
MEKを保存し、機密性を保持する必要があります。Go のバージョンは 1.18 以降である必要があります。
手順
1. ドライバを取得する
alibabacloud-encdb-mysql-go-client は、MySQL Community エディション 用の Go-MySQL-Driver と完全に互換性があり、標準 Go の database/sql/driver 操作をサポートしています。 この場合、コードを変更せずにデータベース接続を確立できます。
ドライバのオープンソースコードは GitHub で入手できます。 詳細については、alibabacloud-encdb-mysql-go-client をご参照ください。
次のコマンドを実行して、ドライバを取得します。
go get github.com/aliyun/alibabacloud-encdb-mysql-go-client@latest2. 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 for MySQL データベースの暗号化されたカラムのプレーンテキストデータを表示します。
以下のサンプルコードのデータベース構成の詳細については、列の暗号化 セクションの「PolarDB for 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) // データの読み取り:
}
}上記のコードが呼び出されると、次の情報に類似した復号結果が返されます。
