Selalu Dienkripsi dengan go-mssqldb

Driver mendukung go-mssqldbAlways Encrypted untuk enkripsi sisi klien dan dekripsi data sensitif. Saat diaktifkan, driver secara otomatis mendekripsi data dari kolom terenkripsi dan mengenkripsi nilai parameter yang dikirim ke kolom terenkripsi.

Aktifkan Selalu Terenkripsi

Atur parameter sambungan columnencryption ke true:

sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&columnencryption=true

Anda juga perlu mengimpor setidaknya satu paket penyedia kunci utama kolom (CMK). Tanpa penyedia, driver tidak dapat mengakses kunci enkripsi.

Penyedia kunci utama kolom

Driver tersebut mendukung tiga penyedia penyimpanan kunci utama. Impor paket penyedia sebagai impor efek samping untuk mendaftarkannya.

Sertifikat lokal (PFX)

Penyedia localcert membaca kunci pribadi dari file PFX (PKCS #12) pada sistem file lokal. Nama penyedia dalam metadata CMK adalah pfx.

import (
    _ "github.com/microsoft/go-mssqldb"
    _ "github.com/microsoft/go-mssqldb/aecmk/localcert"
)

Saat mengonfigurasi CMK di SQL Server, atur jalur kunci ke lokasi file PFX:

CREATE COLUMN MASTER KEY MyCMK
WITH (
    KEY_STORE_PROVIDER_NAME = 'pfx',
    KEY_PATH = '/path/to/certificate.pfx'
);

Jika file PFX dilindungi kata sandi, atur kata sandi sebagai variabel lingkungan atau melalui pfxpassword parameter koneksi.

Penyimpanan Sertifikat Windows

MSSQL_CERTIFICATE_STORE Penyedia mengakses sertifikat di Penyimpanan Sertifikat Windows. Penyedia ini hanya berfungsi di Windows.

import (
    _ "github.com/microsoft/go-mssqldb"
    _ "github.com/microsoft/go-mssqldb/aecmk/localcert"
)

Note

Impor localcert juga mendaftarkan penyedia Windows Certificate Store di Windows. Tidak diperlukan impor terpisah.

Format jalur kunci CMK adalah CurrentUser/My/<thumbprint> atau LocalMachine/My/<thumbprint>:

CREATE COLUMN MASTER KEY MyCMK
WITH (
    KEY_STORE_PROVIDER_NAME = 'MSSQL_CERTIFICATE_STORE',
    KEY_PATH = 'CurrentUser/My/<CERTIFICATE_THUMBPRINT>'
);

Azure Key Vault

Penyedia akv mengambil kunci master kolom dari Azure Key Vault.

import (
    _ "github.com/microsoft/go-mssqldb"
    _ "github.com/microsoft/go-mssqldb/aecmk/akv"
)

Jalur kunci CMK adalah URL pengidentifikasi kunci Azure Key Vault:

CREATE COLUMN MASTER KEY MyCMK
WITH (
    KEY_STORE_PROVIDER_NAME = 'AZURE_KEY_VAULT',
    KEY_PATH = 'https://<VAULT_NAME>.vault.azure.net/keys/<KEY_NAME>/<KEY_VERSION>'
);

Penyedia Azure Key Vault menggunakan azidentity.DefaultAzureCredential untuk autentikasi. Konfigurasikan kredensial melalui variabel lingkungan, identitas terkelola, Azure CLI, atau metode lain yang didukung oleh pustaka Azure Identity. Untuk informasi selengkapnya, lihat Autentikasi ID Microsoft Entra.

Mengkueri kolom terenkripsi

Dengan Always Encrypted diaktifkan dan penyedia terdaftar, kueri bekerja secara transparan:

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

    _ "github.com/microsoft/go-mssqldb"
    _ "github.com/microsoft/go-mssqldb/aecmk/localcert"
)

func main() {
    db, err := sql.Open("sqlserver",
        "sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&columnencryption=true")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    ctx := context.Background()

    // Reads automatically decrypt encrypted columns
    var ssn string
    err = db.QueryRowContext(ctx,
        "SELECT SSN FROM Patients WHERE Id = @p1",
        sql.Named("p1", 1)).Scan(&ssn)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("SSN:", ssn)

    // Parameters are automatically encrypted for encrypted columns
    _, err = db.ExecContext(ctx,
        "INSERT INTO Patients (Name, SSN) VALUES (@p1, @p2)",
        sql.Named("p1", "Alice"),
        sql.Named("p2", "123-45-6789"))
    if err != nil {
        log.Fatal(err)
    }
}

Cocokkan jenis parameter dengan tepat

Enkripsi parameter Always Encrypted lebih ketat daripada pengikatan parameter biasa. Driver meminta metadata enkripsi SQL Server sebelum mengirim nilai, sehingga jenis parameter Go harus cocok dengan jenis kolom SQL Server.

  • Parameter Go string dikirim sebagai nvarchar secara default.
  • Gunakan jenis khusus driver seperti mssql.NVarCharMax, mssql.DateTime1, atau mssql.DateTimeOffset ketika kolom terenkripsi menggunakan jenis SQL Server yang lebih spesifik.
  • Jika jenis parameter tidak cocok dengan jenis kolom terenkripsi, kueri dapat gagal selama penemuan metadata enkripsi parameter dengan kesalahan ketidakcocokan jenis.

Misalnya, jika kolom terenkripsi adalah nvarchar(max), lebih suka mssql.NVarCharMax saat Anda memerlukan pencocokan string besar yang tepat:

_, err := db.ExecContext(ctx,
    "INSERT INTO Patients (Notes) VALUES (@p1)",
    sql.Named("p1", mssql.NVarCharMax("Sensitive note text")))

Untuk panduan jenis parameter umum, lihat Pemetaan tipe data.

Keterbatasan

  • Always Encrypted tidak berfungsi dengan operasi penyalinan massal.
  • Driver azuresql dan Always Encrypted dapat digabungkan, tetapi Anda harus mengimpor paket azuread dan paket penyedia kunci.
  • Penyisipan dan pembaruan terenkripsi char dan varchar saat ini terbatas. Gunakan kolom nchar atau nvarchar yang dienkripsi untuk data teks yang harus menggunakan Always Encrypted.
  • Enklave aman tidak didukung.