ApsaraDB RDS for MySQL または PolarDB for MySQL データベースで列レベルの暗号化を有効にした後、Go アプリケーションで alibabacloud-encdb-mysql-go-client ドライバーを使用して、暗号化列からプレーンテキストデータにアクセスします。
背景情報
列レベルの暗号化は、特定の列にデータを暗号文として保存することでデータセキュリティを強化します。権限を持つクライアントは、このデータにプレーンテキストとして透過的にアクセスできます。
Alibaba Cloud は、クライアント側の Go ドライバーである alibabacloud-encdb-mysql-go-client を提供します。暗号化データベースにアクセスするには、このドライバーを使用して接続し、データベース接続 URL にマスター暗号化キー (MEK) を指定します。ドライバーは暗号文を自動的に復号し、プレーンテキストデータを返します。
クライアントとサーバーは、安全な非対称暗号化プロトコルを使用して MEK を送信します。このプロセスにより、両者の間で共有鍵が確立され、安全な対称データ暗号化が可能になります。
値の範囲:長さが正確に 32 文字の 16 バイトの 16 進数文字列です。
MEK は、クライアントが暗号化データにアクセスすることを許可するルート認証情報です。セキュリティ上の理由から、暗号化データベースは MEK を保存または管理せず、MEK の生成やバックアップのサービスも提供しません。お客様自身で MEK を生成する必要があります。MEK の保護はデータベースセキュリティにおいて極めて重要です。MEK は安全な場所にバックアップすることを推奨します。
前提条件
-
ターゲットデータベースの列の暗号化を有効にし、ターゲットデータベースアカウントの暗号文の権限を Ciphertext Permission (JDBC Decryption) に設定します。データベースの列の暗号化とアカウントの権限の設定に関する詳細については、「データベースの列の暗号化を設定する」をご参照ください。
-
暗号化されたデータベースの接続情報 (エンドポイント、ポート、データベース名、データベースアカウント、パスワード) を取得しておきます。
使用上の注意
-
マスター暗号化キー (
MEK) を安全に保管してください。 -
Go 1.18 以降が必要です。
クライアントの統合
1. ドライバーの取得
alibabacloud-encdb-mysql-go-client は、コミュニティの Go MySQL ドライバーおよび標準の Go database/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)、ユーザー名、パスワードに置き換えてください。
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)
}
完全なコード例
次の例では、[Ciphertext Permission (JDBC Decryption)] を持つデータベースアカウントを使用して、PolarDB for MySQL データベースの暗号化列からプレーンテキストデータをクエリします。
この例で使用するデータベース設定の詳細は、「Column encryption」トピックの Column encryption example for a PolarDB for MySQL database セクションをご参照ください。
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/aliyun/alibabacloud-encdb-mysql-go-client"
)
func main() {
// プレースホルダーを実際のエンドポイント (hostname)、ポート番号 (port)、データベース名 (dbname)、ユーザー名、パスワードに置き換えてください。
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)
}
}
コードを実行すると、復号後の出力は次のようになります:
read data: id=1, name=2clxxx, password=xxx, age=3
read data: id=2, name=RZlxxx6Z=, password=)xxxv9>, age=4
read data: id=3, name=!xxxrm, password=kxxxS, age=5