Gunakan Always Encrypted dengan driver JDBC
Halaman ini menyediakan informasi tentang cara mengembangkan aplikasi Java untuk menggunakan Always Encrypted dengan Microsoft JDBC Driver 6.0 (atau lebih tinggi) untuk SQL Server.
Always Encrypted memungkinkan klien mengenkripsi data sensitif dan tidak pernah mengungkapkan data atau kunci enkripsi ke SQL Server atau Azure SQL Database. Driver yang diaktifkan Always Encrypted, seperti Microsoft JDBC Driver 6.0 (atau lebih tinggi) untuk SQL Server, mencapai perilaku ini dengan mengenkripsi dan mendekripsi data sensitif secara transparan di aplikasi klien. Driver mencari tahu parameter kueri mana yang sesuai dengan kolom database Always Encrypted, dan mengenkripsi nilai parameter tersebut sebelum mengirimkannya ke database. Demikian pula, driver secara transparan mendekripsi data yang diambil dari kolom database terenkripsi dalam hasil kueri. Untuk informasi selengkapnya, lihat Referensi Always Encrypted (Mesin Database) dan Always Encrypted API untuk driver JDBC.
Prasyarat
- Pastikan Microsoft JDBC Driver 6.0 (atau lebih tinggi) untuk SQL Server diinstal pada komputer pengembangan Anda.
- Unduh dan instal File Kebijakan Yurisdiksi Kekuatan Tak Terbatas Ekstensi Kriptografi Java (JCE). Pastikan untuk membaca Readme yang disertakan dalam file zip untuk instruksi penginstalan, dan detail yang relevan tentang kemungkinan masalah ekspor atau impor.
- Untuk mssql-jdbc-X.X.X.jre7.jar atau sqljdbc41.jar, file kebijakan dapat diunduh dari Unduhan Java Cryptography Extension (JCE) Unlimited Strength Yurisdiction Policy Files 7
- Untuk mssql-jdbc-X.X.X.jre8.jar atau sqljdbc42.jar, file kebijakan dapat diunduh dari Java Cryptography Extension (JCE) Unlimited Strength Yurisdiction Policy Files 8 Download
- Untuk JRE versi 9 atau yang lebih tinggi (misalnya, mssql-jdbc-X.X.X.jre9.jar), tidak ada file kebijakan yang perlu diunduh. Kebijakan yurisdiksi di Java 9, dan lebih besar, default ke enkripsi kekuatan tak terbatas.
Bekerja dengan penyimpanan kunci master kolom
Untuk mengenkripsi atau mendekripsi data untuk kolom terenkripsi, SQL Server mempertahankan kunci enkripsi kolom. Kunci enkripsi kolom disimpan dalam formulir terenkripsi dalam metadata database. Setiap kunci enkripsi kolom memiliki kunci master kolom terkait yang digunakan untuk mengenkripsi kunci enkripsi kolom.
Metadata database tidak berisi kunci master kolom. Kunci tersebut hanya dipegang oleh klien. Namun metadata database memang berisi informasi tentang di mana kunci master kolom disimpan relatif terhadap klien. Misalnya, metadata database mungkin mengatakan keystore yang menyimpan kunci master kolom adalah Windows Certificate Store, dan sertifikat tertentu yang digunakan untuk mengenkripsi dan mendekripsi terletak di jalur tertentu dalam Windows Certificate Store.
Jika klien memiliki akses ke sertifikat tersebut di Windows Certificate Store, klien dapat memperoleh sertifikat. Sertifikat kemudian dapat digunakan untuk mendekripsi kunci enkripsi kolom. Kemudian kunci enkripsi tersebut dapat digunakan untuk mendekripsi atau mengenkripsi data untuk kolom terenkripsi yang menggunakan kunci enkripsi kolom tersebut.
Driver Microsoft JDBC untuk SQL Server berkomunikasi dengan keystore yang menggunakan penyedia penyimpanan kunci master kolom, yang merupakan instans kelas yang berasal dari SQLServerColumnEncryptionKeyStoreProvider
.
Menggunakan penyedia penyimpanan kunci master kolom bawaan
Driver Microsoft JDBC untuk SQL Server dilengkapi dengan penyedia penyimpanan kunci master kolom bawaan berikut. Beberapa penyedia ini telah terdaftar sebelumnya dengan nama penyedia tertentu (digunakan untuk mencari penyedia) dan beberapa memerlukan kredensial tambahan atau pendaftaran eksplisit.
Kelas | Deskripsi | Nama penyedia (pencarian) | Apakah sudah terdaftar sebelumnya? | Platform |
---|---|---|---|---|
SQLServerColumnEncryptionAzureKeyVaultProvider |
Penyedia untuk keystore untuk Azure Key Vault. | AZURE_KEY_VAULT | Tidak sebelum driver JDBC versi 7.4.1, tetapi ya pada driver JDBC versi 7.4.1. | Windows, Linux, macOS |
SQLServerColumnEncryptionCertificateStoreProvider |
Penyedia untuk Penyimpanan Sertifikat Windows. | MSSQL_CERTIFICATE_STORE | Ya | Windows |
SQLServerColumnEncryptionJavaKeyStoreProvider |
Penyedia untuk keystore Java. | MSSQL_JAVA_KEYSTORE | Ya | Windows, Linux, macOS |
Untuk penyedia keystore yang telah terdaftar sebelumnya, Anda tidak memerlukan perubahan kode aplikasi apa pun untuk menggunakan penyedia ini tetapi perhatikan item berikut:
- Anda harus memastikan nama penyedia yang dikonfigurasi dalam metadata kunci master kolom sudah benar dan jalur kunci master kolom mengikuti format jalur kunci yang valid untuk penyedia tertentu. Disarankan agar Anda mengonfigurasi kunci dengan alat seperti SQL Server Management Studio, yang secara otomatis menghasilkan nama penyedia dan jalur kunci yang valid untuk mengeluarkan
CREATE COLUMN MASTER KEY
pernyataan (Transact-SQL). - Pastikan aplikasi Anda dapat mengakses kunci di keystore. Tugas ini mungkin melibatkan pemberian akses aplikasi Anda ke kunci dan/atau keystore. Bergantung pada keystore, ini mungkin melibatkan langkah-langkah konfigurasi khusus keystore lainnya. Misalnya, untuk menggunakan
SQLServerColumnEncryptionJavaKeyStoreProvider
, Anda harus menyediakan lokasi dan kata sandi keystore di properti koneksi.
Semua penyedia keystore ini dijelaskan secara lebih rinci di bagian berikut. Anda hanya perlu menerapkan satu penyedia keystore untuk menggunakan Always Encrypted.
Menggunakan penyedia Azure Key Vault
Azure Key Vault adalah opsi yang nyaman untuk menyimpan dan mengelola kunci master kolom untuk Always Encrypted (terutama jika aplikasi Anda dihosting di Azure). Microsoft JDBC Driver untuk SQL Server menyertakan penyedia bawaan, SQLServerColumnEncryptionAzureKeyVaultProvider
, untuk aplikasi yang memiliki kunci yang disimpan di Azure Key Vault. Nama penyedia ini AZURE_KEY_VAULT.
Catatan
Penyedia Azure Key Vault bawaan driver JDBC mendukung Vault dan HSM Terkelola di Azure Key Vault.
Untuk menggunakan penyedia penyimpanan Azure Key Vault, pengembang aplikasi harus membuat brankas dan kunci di Azure Key Vault dan membuat pendaftaran Aplikasi di ID Microsoft Entra (sebelumnya Azure Active Directory). Aplikasi terdaftar harus diberikan izin Dapatkan, Dekripsi, Enkripsi, Buka Bungkus, Kunci Bungkus, dan Verifikasi dalam kebijakan Akses yang ditentukan untuk brankas kunci yang dibuat untuk digunakan dengan Always Encrypted. Untuk informasi selengkapnya tentang cara menyiapkan brankas kunci dan membuat kunci master kolom, lihat Azure Key Vault—Langkah demi Langkah dan Membuat Kunci Master Kolom di Azure Key Vault.
Untuk penyedia Azure Key Vault, driver JDBC memvalidasi jalur kunci master kolom terhadap daftar titik akhir tepercaya. Pada versi 8.2.2, daftar ini dapat dikonfigurasi: buat mssql-jdbc.properties
file di direktori kerja aplikasi, atur AKVTrustedEndpoints
properti ke daftar yang dibatasi titik koma. Jika nilai dimulai dengan titik koma, nilai akan memperluas daftar default. Jika tidak, ini menggantikan daftar default.
Titik akhir tepercaya default adalah:
*vault.azure.net
*vault.azure.cn
*vault.usgovcloudapi.net
*vault.microsoftazure.de
*managedhsm.azure.net
(v9.2+)*managedhsm.azure.cn
(v9.2+)*managedhsm.usgovcloudapi.net
(v9.2+)*managedhsm.microsoftazure.de
(v9.2+)
Untuk contoh di halaman ini, jika Anda telah membuat kunci master kolom berbasis Azure Key Vault dan kunci enkripsi kolom dengan SQL Server Management Studio, skrip T-SQL untuk membuatnya kembali mungkin terlihat mirip dengan contoh ini dengan KEY_PATH dan ENCRYPTED_VALUE spesifiknya sendiri:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'AZURE_KEY_VAULT',
KEY_PATH = N'https://<MyKeyVaultName>.vault.azure.net:443/keys/Always-Encrypted-Auto1/c61f01860f37302457fa512bb7e7f4e8'
);
CREATE COLUMN ENCRYPTION KEY [MyCEK]
WITH VALUES
(
COLUMN_MASTER_KEY = [MyCMK],
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x01BA000001680074507400700073003A002F002F006400610076006...
);
Aplikasi yang menggunakan driver JDBC dapat menggunakan Azure Key Vault. Sintaks atau pernyataan untuk penggunaan Azure Key Vault ini berubah per dengan driver JDBC versi 7.4.1.
Driver JDBC 7.4.1 atau yang lebih baru
Bagian ini melibatkan driver JDBC versi 7.4.1 atau yang lebih baru.
Aplikasi klien yang menggunakan driver JDBC dapat mengonfigurasi untuk menggunakan Azure Key Vault dengan menyebutkan keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>
di JDBC string koneksi.
Berikut adalah contoh yang menyediakan informasi konfigurasi ini dalam string koneksi JDBC.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>";
Driver JDBC secara otomatis membuat instans SQLServerColumnEncryptionAzureKeyVaultProvider
objek ketika kredensial ini ada di antara properti koneksi.
Penting
Properti keyVaultProviderClientId
koneksi dan keyVaultProviderClientKey
telah tidak digunakan lagi pada v8.4.1. Pengguna didorong untuk menggunakan keyStoreAuthentication
, KeyStorePrincipalId
, dan KeyStoreSecret
sebagai gantinya.
Versi driver JDBC sebelum 7.4.1
Bagian ini melibatkan versi driver JDBC sebelum 7.4.1.
Aplikasi klien yang menggunakan driver JDBC harus membuat instans SQLServerColumnEncryptionAzureKeyVaultProvider
objek, lalu mendaftarkan objek dengan driver.
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
clientID
adalah ID Aplikasi pendaftaran Aplikasi di penyewa Microsoft Entra. clientKey
adalah Kata Sandi Kunci yang terdaftar di bawah Aplikasi tersebut, yang menyediakan akses API ke Azure Key Vault.
Setelah aplikasi membuat instans SQLServerColumnEncryptionAzureKeyVaultProvider
, aplikasi harus mendaftarkan instans dengan driver dengan SQLServerConnection.registerColumnEncryptionKeyStoreProviders()
metode . Sangat disarankan agar instans terdaftar menggunakan nama pencarian default, AZURE_KEY_VAULT, yang dapat diperoleh oleh SQLServerColumnEncryptionAzureKeyVaultProvider.getName()
API. Nama default memungkinkan Anda menggunakan alat seperti SQL Server Management Studio atau PowerShell untuk menyediakan dan mengelola kunci Always Encrypted (alat menggunakan nama default untuk menghasilkan objek metadata ke kunci master kolom). Contoh berikut menunjukkan mendaftarkan penyedia Azure Key Vault. Untuk informasi selengkapnya tentang metode ini SQLServerConnection.registerColumnEncryptionKeyStoreProviders()
, lihat Referensi ALWAYS Encrypted API untuk Driver JDBC.
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Penting
Jika Anda menggunakan penyedia keystore Azure Key Vault, implementasi Azure Key Vault driver JDBC memiliki dependensi pada pustaka ini (dari GitHub) yang harus disertakan dengan aplikasi Anda:
pustaka microsoft-authentication-library-for-java
Untuk contoh cara menyertakan dependensi ini dalam proyek Maven, lihat Mengunduh Dependensi MSAL4J dan AKV dengan Apache Maven
Menggunakan autentikasi Azure Key Vault dengan Identitas Terkelola
Pada Driver JDBC 8.4.1, driver menambahkan dukungan untuk mengautentikasi ke Azure Key Vaults dengan Identitas Terkelola.
Anda dapat menggunakan Identitas Terkelola untuk mengautentikasi ke Azure Key Vault jika aplikasi dihosting di Azure. Ini menghilangkan kebutuhan untuk memberikan dan mengekspos info masuk apa pun dalam kode.
Properti koneksi untuk autentikasi Key Vault dengan Identitas Terkelola
Untuk Driver JDBC 8.4.1 dan yang lebih baru, driver memperkenalkan properti koneksi berikut:
ConnectionProperty | Kemungkinan Pasangan Nilai 1 | Kemungkinan Pasangan Nilai 2 | Kemungkinan Pasangan Nilai 3 |
---|---|---|---|
keyStoreAuthentication | KeyVaultClientSecret | KeyVaultManagedIdentity | JavaKeyStorePassword |
keyStorePrincipalId | <ID Klien Aplikasi Microsoft Entra> | <ID> objek Aplikasi Microsoft Entra (opsional) | n/a |
keyStoreSecret | <Rahasia Klien Aplikasi Microsoft Entra> | n/a | <rahasia/kata sandi untuk Java Key Store> |
Contoh berikut menunjukkan bagaimana properti koneksi digunakan dalam string koneksi.
Menggunakan Identitas Terkelola untuk mengautentikasi ke AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;"
Gunakan Identitas Terkelola dan ID utama untuk mengautentikasi ke AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;keyStorePrincipal=<principalId>"
Menggunakan clientId dan clientSecret untuk autentikasi ke AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultClientSecret;keyStorePrincipalId=<clientId>;keyStoreSecret=<clientSecret>"
Pengguna didorong untuk menggunakan properti koneksi ini untuk menentukan jenis autentikasi yang digunakan untuk Key Stores alih-alih SQLServerColumnEncryptionAzureKeyVaultProvider
API.
Properti koneksi keyVaultProviderClientId
yang sebelumnya ditambahkan dan keyVaultProviderClientKey
tidak digunakan lagi dan digantikan oleh properti koneksi yang dijelaskan sebelumnya.
Untuk informasi tentang cara mengonfigurasi Identitas Terkelola, lihat Mengonfigurasi identitas terkelola untuk sumber daya Azure pada VM menggunakan portal Azure.
Menggunakan penyedia Windows Certificate Store
SQLServerColumnEncryptionCertificateStoreProvider
dapat digunakan untuk menyimpan kunci master kolom di Penyimpanan Sertifikat Windows. Gunakan wizard Always Encrypted SQL Server Management Studio (SSMS) atau alat lain yang didukung untuk membuat kunci master kolom dan definisi kunci enkripsi kolom dalam database. Wizard yang sama dapat digunakan untuk menghasilkan sertifikat yang ditandatangani sendiri di Penyimpanan Sertifikat Windows yang dapat digunakan sebagai kunci master kolom untuk data Always Encrypted. Untuk informasi selengkapnya tentang kunci master kolom dan sintaks T-SQL kunci enkripsi kolom, lihat MEMBUAT KUNCI MASTER KOLOM dan MEMBUAT KUNCI ENKRIPSI KOLOM masing-masing.
Nama MSSQL_CERTIFICATE_STORE dan dapat dikueri SQLServerColumnEncryptionCertificateStoreProvider
oleh API getName() objek penyedia. Ini secara otomatis didaftarkan oleh driver dan dapat digunakan dengan mulus tanpa perubahan aplikasi apa pun.
Untuk contoh di halaman ini, jika Anda telah membuat kunci master kolom berbasis Windows Certificate Store dan kunci enkripsi kolom dengan SQL Server Management Studio, skrip T-SQL untuk membuatnya kembali mungkin terlihat mirip dengan contoh ini dengan KEY_PATH dan ENCRYPTED_VALUE spesifiknya sendiri:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
KEY_PATH = N'CurrentUser/My/A2A91F59C461B559E4D962DA9D2BC6131B32CB91'
);
CREATE COLUMN ENCRYPTION KEY [MyCEK]
WITH VALUES
(
COLUMN_MASTER_KEY = [MyCMK],
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x016E000001630075007200720065006E0074007500730065007200...
);
Penting
Meskipun penyedia keystore lainnya dalam artikel ini tersedia di semua platform yang didukung oleh driver, SQLServerColumnEncryptionCertificateStoreProvider
implementasi driver JDBC hanya tersedia pada sistem operasi Windows. Ini memiliki dependensi pada mssql-jdbc_auth-<version>-<arch>.dll
yang tersedia dalam paket driver. Untuk menggunakan penyedia ini, salin mssql-jdbc_auth-<version>-<arch>.dll
file ke direktori pada jalur sistem Windows pada komputer tempat pengandar JDBC diinstal. Atau Anda dapat mengatur properti sistem java.library.path untuk menentukan direktori mssql-jdbc_auth-<version>-<arch>.dll
. Jika Anda menjalankan Java Virtual Machine (JVM) 32-bit, gunakan mssql-jdbc_auth-<version>-x86.dll
file di folder x86, bahkan jika sistem operasi adalah versi x64. Jika Anda menjalankan JVM 64-bit pada prosesor x64, gunakan mssql-jdbc_auth-<version>-x64.dll
file di folder x64. Misalnya, jika Anda menggunakan JVM 32-bit dan driver JDBC diinstal di direktori default, Anda dapat menentukan lokasi DLL dengan argumen komputer virtual (VM) berikut saat aplikasi Java dimulai: -Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86
Menggunakan penyedia Java Key Store
Driver JDBC dilengkapi dengan implementasi penyedia keystore bawaan untuk Java Key Store. keyStoreAuthentication
Jika properti string koneksi ada di string koneksi dan diatur ke JavaKeyStorePassword
, driver secara otomatis membuat instans dan mendaftarkan penyedia untuk Java Key Store. Nama penyedia Java Key Store MSSQL_JAVA_KEYSTORE. Nama ini juga dapat dikueri oleh SQLServerColumnEncryptionJavaKeyStoreProvider.getName()
API.
Ada tiga properti string koneksi yang memungkinkan aplikasi klien menentukan kredensial yang perlu diautentikasi driver ke Java Key Store. Driver menginisialisasi penyedia berdasarkan nilai ketiga properti ini dalam string koneksi.
keyStoreAuthentication
: Mengidentifikasi Java Key Store yang akan digunakan. Dengan Microsoft JDBC Driver 6.0 dan yang lebih tinggi untuk SQL Server, Anda dapat mengautentikasi ke Java Key Store hanya melalui properti ini. Untuk Java Key Store, nilai untuk properti ini harus JavaKeyStorePassword
.
keyStoreLocation
: Jalur ke file Java Key Store yang menyimpan kunci master kolom. Jalur ini mencakup nama file keystore.
keyStoreSecret
: Rahasia/kata sandi yang akan digunakan untuk keystore dan kunci. Untuk menggunakan Java Key Store, keystore dan kata sandi kunci harus sama.
Berikut adalah contoh penyediaan kredensial ini di string koneksi:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=<path_to_the_keystore_file>;keyStoreSecret=<keystore_key_password>";
Anda juga bisa mendapatkan atau mengatur pengaturan ini dengan SQLServerDataSource
objek . Untuk informasi selengkapnya, lihat Referensi ALWAYS Encrypted API untuk Driver JDBC.
Driver JDBC secara otomatis membuat instans SQLServerColumnEncryptionJavaKeyStoreProvider
kapan kredensial ini ada di properti koneksi.
Membuat kunci master kolom untuk Java Key Store
SQLServerColumnEncryptionJavaKeyStoreProvider
dapat digunakan dengan jenis keystore JKS atau PKCS12. Untuk membuat atau mengimpor kunci yang akan digunakan dengan penyedia ini, gunakan utilitas keytool Java. Kunci harus memiliki kata sandi yang sama dengan keystore itu sendiri. Berikut adalah contoh cara membuat kunci umum dan kunci privat terkait dengan keytool
utilitas:
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.jks -storepass mypassword -validity 360 -keysize 2048 -storetype jks
Perintah ini membuat kunci publik dan membungkusnya dalam sertifikat X.509 yang ditandatangani sendiri, yang disimpan di keystore keystore.jks
bersama dengan kunci privat terkait. Entri ini di keystore diidentifikasi oleh alias AlwaysEncryptedKey
.
Berikut adalah contoh yang sama dengan jenis penyimpanan PKCS12:
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.pfx -storepass mypassword -validity 360 -keysize 2048 -storetype pkcs12 -keypass mypassword
Jika keystore berjenis PKCS12, utilitas keytool tidak meminta kata sandi kunci dan kata sandi kunci perlu disediakan dengan -keypass
opsi karena SQLServerColumnEncryptionJavaKeyStoreProvider
mengharuskan keystore dan kunci memiliki kata sandi yang sama.
Anda juga dapat mengekspor sertifikat dari penyimpanan Sertifikat Windows dalam format .pfx dan menggunakannya SQLServerColumnEncryptionJavaKeyStoreProvider
dengan . Sertifikat yang diekspor juga dapat diimpor ke Java Key Store sebagai jenis keystore JKS.
Setelah Anda membuat entri keytool, buat metadata kunci master kolom di database, yang memerlukan nama penyedia keystore dan jalur kunci. Untuk informasi selengkapnya tentang cara membuat data meta kunci master kolom, lihat MEMBUAT KUNCI MASTER KOLOM. Untuk SQLServerColumnEncryptionJavaKeyStoreProvider
, jalur kunci hanyalah alias kunci dan nama SQLServerColumnEncryptionJavaKeyStoreProvider
adalah MSSQL_JAVA_KEYSTORE
. Anda juga dapat mengkueri getName()
nama ini dengan API SQLServerColumnEncryptionJavaKeyStoreProvider
publik kelas.
Sintaks T-SQL untuk membuat kunci master kolom adalah:
CREATE COLUMN MASTER KEY [<CMK_name>]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'<key_alias>'
);
Untuk 'AlwaysEncryptedKey' yang dibuat sebelumnya, definisi kunci master kolom adalah:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'AlwaysEncryptedKey'
);
Catatan
Fungsionalitas SQL Server management Studio bawaan tidak dapat membuat definisi kunci master kolom untuk Java Key Store. Perintah T-SQL harus digunakan secara terprogram.
Membuat kunci enkripsi kolom untuk Java Key Store
SQL Server Management Studio atau alat lain tidak dapat digunakan untuk membuat kunci enkripsi kolom menggunakan kunci master kolom di Java Key Store. Aplikasi klien harus membuat kunci enkripsi kolom secara terprogram dengan SQLServerColumnEncryptionJavaKeyStoreProvider
kelas . Untuk informasi selengkapnya, lihat Menggunakan penyedia penyimpanan kunci master kolom untuk provisi kunci terprogram.
Menerapkan penyedia penyimpanan kunci master kolom kustom
Jika Anda ingin menyimpan kunci master kolom di keystore yang tidak didukung oleh penyedia yang ada, Anda dapat menerapkan penyedia kustom dengan memperluas SQLServerColumnEncryptionKeyStoreProvider
Kelas dan mendaftarkan penyedia dengan salah satu metode berikut:
SQLServerConnection.registerColumnEncryptionKeyStoreProviders
SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection
(Ditambahkan dalam JDBC versi 10.2)SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement
(Ditambahkan dalam JDBC versi 10.2)
public class MyCustomKeyStore extends SQLServerColumnEncryptionKeyStoreProvider{
private String name = "MY_CUSTOM_KEYSTORE";
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public byte[] encryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm, byte[] plainTextColumnEncryptionKey)
{
// Logic for encrypting the column encryption key
}
public byte[] decryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm, byte[] encryptedColumnEncryptionKey)
{
// Logic for decrypting the column encryption key
}
}
Daftarkan penyedia dengan SQLServerConnection.registerColumnEncryptionKeyStoreProviders
:
SQLServerColumnEncryptionKeyStoreProvider storeProvider = new MyCustomKeyStore();
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(storeProvider.getName(), storeProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Prioritas cache kunci enkripsi kolom
Bagian ini berlaku untuk driver JDBC versi 10.2 dan yang lebih tinggi.
Kunci enkripsi kolom (CEK) yang didekripsi oleh penyedia penyimpanan kunci kustom yang terdaftar pada koneksi atau instans pernyataan tidak akan di-cache oleh Driver Microsoft JDBC untuk SQL Server. Penyedia penyimpanan kunci kustom harus menerapkan mekanisme penembolokan CEK mereka sendiri.
Pada versi 10.2, SQLServerColumnEncryptionAzureKeyVaultProvider
memiliki implementasi penembolokan CEK sendiri. Ketika terdaftar pada koneksi atau instans pernyataan, CEK yang didekripsi oleh instans SQLServerColumnEncryptionAzureKeyVaultProvider
akan dibersihkan ketika instans tersebut keluar dari cakupan:
try (SQLServerConnection conn = getConnection(); SQLServerStatement stmt = (SQLServerStatement) conn.createStatement()) {
Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
stmt.registerColumnEncryptionKeyStoreProvidersOnStatement(customKeyStoreProviders);
// Perform database operation with Azure Key Vault Provider
// Any decrypted column encryption keys will be cached
} // Column encryption key cache of "akvProvider" is cleared when "akvProvider" goes out of scope
Catatan
Penembolokan CEK yang diterapkan oleh penyedia penyimpanan kunci kustom akan dinonaktifkan oleh driver jika instans penyedia penyimpanan kunci terdaftar di driver secara global dengan metode .SQLServerConnection.registerColumnEncryptionKeyStoreProviders
Setiap implementasi penembolokan CEK harus mereferensikan nilai durasi time-to-live sebelum penembolokan CEK dan tidak menyimpannya jika nilainya nol. Ini akan menghindari penembolokan duplikat dan kemungkinan kebingungan pengguna saat mereka mencoba mengonfigurasi penembolokan kunci. Nilai time-to-live untuk cache dapat diatur dengan SQLServerColumnEncryptionKeyStoreProvider.setColumnEncryptionCacheTtl
metode .
Mendaftarkan penyedia penyimpanan kunci master kolom kustom
Bagian ini berlaku untuk driver JDBC versi 10.2 dan yang lebih tinggi.
Penyedia penyimpanan kunci master kustom dapat didaftarkan dengan driver pada tiga lapisan yang berbeda. Prioritas dari tiga pendaftaran adalah sebagai berikut:
- Pendaftaran per pernyataan diperiksa jika tidak kosong.
- Jika pendaftaran per pernyataan kosong, pendaftaran per koneksi diperiksa jika tidak kosong.
- Jika pendaftaran per koneksi kosong, pendaftaran global akan diperiksa.
Setelah penyedia penyimpanan kunci ditemukan pada tingkat pendaftaran, driver TIDAK akan kembali ke pendaftaran lain untuk mencari penyedia. Jika penyedia terdaftar tetapi penyedia yang tepat tidak ditemukan pada tingkat, pengecualian dilemparkan yang hanya berisi penyedia terdaftar dalam pendaftaran yang diperiksa.
Penyedia penyimpanan kunci master kolom bawaan yang tersedia untuk Penyimpanan Sertifikat Windows telah didaftarkan sebelumnya. Penyedia Microsoft Java Keystore dan penyedia Keystore Azure Key Vault dapat secara implisit terdaftar dengan instans koneksi jika kredensial disediakan terlebih dahulu.
Tiga tingkat pendaftaran mendukung skenario yang berbeda saat mengkueri data terenkripsi. Metode yang sesuai dapat digunakan untuk memastikan bahwa pengguna aplikasi dapat mengakses data teks biasa. Akses ke data yang tidak terenkripsi hanya terjadi jika mereka dapat memberikan kunci master kolom yang diperlukan, dengan mengautentikasi terhadap penyimpanan kunci yang berisi kunci master kolom.
Aplikasi yang berbagi SQLServerConnection
instans antara beberapa pengguna mungkin ingin menggunakan SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement
. Setiap pengguna harus mendaftarkan penyedia penyimpanan kunci pada SQLServerStatement
instans sebelum menjalankan kueri untuk mengakses kolom terenkripsi. Jika penyedia penyimpanan kunci dapat mengakses kunci master kolom yang diperlukan di penyimpanan kunci yang menggunakan kredensial yang diberikan pengguna, kueri akan berhasil.
Aplikasi yang membuat SQLServerConnection
instans untuk setiap pengguna mungkin ingin menggunakan SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection
. Penyedia penyimpanan kunci yang terdaftar dengan metode ini dapat digunakan oleh koneksi untuk setiap kueri yang mengakses data terenkripsi.
Penyedia penyimpanan kunci yang terdaftar SQLServerConnection.registerColumnEncryptionKeyStoreProviders
akan menggunakan identitas yang diberikan oleh aplikasi saat mengautentikasi terhadap penyimpanan kunci.
Contoh berikut menunjukkan prioritas penyedia penyimpanan kunci master kolom kustom yang terdaftar pada instans koneksi:
Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
MyCustomKeyStore myProvider = new MyCustomKeyStore();
customKeyStoreProviders.put(myProvider.getName(), myProvider);
// Registers the provider globally
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
try (SQLServerConnection conn = getConnection()) {
customKeyStoreProviders.clear();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
// Registers the provider on the connection
// These providers will take precedence over globally registered providers
conn.registerColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);
}
Contoh berikut menunjukkan prioritas penyedia penyimpanan kunci master kolom kustom yang terdaftar pada instans pernyataan:
Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
MyCustomKeyStore firstProvider = new MyCustomKeyStore();
customKeyStoreProviders.put("FIRST_CUSTOM_STORE", firstProvider);
// Registers the provider globally
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
try (SQLServerConnection conn = getConnection()) {
customKeyStoreProviders.clear();
MyCustomKeyStore secondProvider = new MyCustomKeyStore();
customKeyStoreProviders.put("SECOND_CUSTOM_STORE", secondProvider);
// Registers the provider on the connection
conn.registerColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);
try (SQLServerStatement stmt = (SQLServerStatement) conn.createStatement()) {
customKeyStoreProviders.clear();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
// Registers the provider on the statement
// These providers will take precedence over connection-level providers and globally registered providers
stmt.registerColumnEncryptionKeyStoreProvidersOnStatement(customKeyStoreProviders);
}
}
Menggunakan penyedia penyimpanan kunci master kolom untuk provisi kunci terprogram
Untuk mengakses kolom terenkripsi, Driver Microsoft JDBC untuk SQL Server secara transparan menemukan dan memanggil penyedia penyimpanan kunci master kolom yang tepat untuk mendekripsi kunci enkripsi kolom. Biasanya, kode aplikasi normal Anda tidak langsung memanggil penyedia penyimpanan kunci master kolom. Namun, Anda dapat membuat instans dan memanggil penyedia secara terprogram untuk menyediakan dan mengelola kunci Always Encrypted. Langkah ini dapat dilakukan untuk menghasilkan kunci enkripsi kolom terenkripsi dan mendekripsi kunci enkripsi kolom sebagai rotasi kunci master kolom bagian, misalnya. Untuk informasi selengkapnya, lihat Gambaran Umum Manajemen Kunci untuk Always Encrypted.
Jika Anda menggunakan penyedia keystore kustom, menerapkan alat manajemen kunci Anda sendiri mungkin diperlukan. Untuk menggunakan kunci yang disimpan di Windows Certificate Store atau di Azure Key Vault, Anda dapat menggunakan alat yang ada, seperti SQL Server Management Studio atau PowerShell, untuk mengelola dan menyediakan kunci. Untuk menggunakan kunci yang disimpan di Java Key Store, Anda perlu menyediakan kunci secara terprogram. Contoh berikut mengilustrasikan cara menggunakan SQLServerColumnEncryptionJavaKeyStoreProvider
kelas untuk mengenkripsi kunci dengan kunci yang disimpan di Java Key Store.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerException;
/**
* This program demonstrates how to create a column encryption key programmatically for the Java Key Store.
*/
public class AlwaysEncrypted {
// Alias of the key stored in the keystore.
private static String keyAlias = "<provide key alias>";
// Name by which the column master key will be known in the database.
private static String columnMasterKeyName = "MyCMK";
// Name by which the column encryption key will be known in the database.
private static String columnEncryptionKey = "MyCEK";
// The location of the keystore.
private static String keyStoreLocation = "C:\\Dev\\Always Encrypted\\keystore.jks";
// The password of the keystore and the key.
private static char[] keyStoreSecret = "********".toCharArray();
/**
* Name of the encryption algorithm used to encrypt the value of the column encryption key. The algorithm for the system providers must be
* RSA_OAEP.
*/
private static String algorithm = "RSA_OAEP";
public static void main(String[] args) {
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
try (Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();) {
// Instantiate the Java Key Store provider.
SQLServerColumnEncryptionKeyStoreProvider storeProvider = new SQLServerColumnEncryptionJavaKeyStoreProvider(keyStoreLocation,
keyStoreSecret);
byte[] encryptedCEK = getEncryptedCEK(storeProvider);
/**
* Create column encryption key For more details on the syntax, see:
* https://learn.microsoft.com/sql/t-sql/statements/create-column-encryption-key-transact-sql Encrypted column encryption key first needs
* to be converted into varbinary_literal from bytes, for which byteArrayToHex() is used.
*/
String createCEKSQL = "CREATE COLUMN ENCRYPTION KEY "
+ columnEncryptionKey
+ " WITH VALUES ( "
+ " COLUMN_MASTER_KEY = "
+ columnMasterKeyName
+ " , ALGORITHM = '"
+ algorithm
+ "' , ENCRYPTED_VALUE = 0x"
+ byteArrayToHex(encryptedCEK)
+ " ) ";
statement.executeUpdate(createCEKSQL);
System.out.println("Column encryption key created with name : " + columnEncryptionKey);
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
private static byte[] getEncryptedCEK(SQLServerColumnEncryptionKeyStoreProvider storeProvider) throws SQLServerException {
String plainTextKey = "You need to give your plain text";
// plainTextKey has to be 32 bytes with current algorithm supported
byte[] plainCEK = plainTextKey.getBytes();
// This will give us encrypted column encryption key in bytes
byte[] encryptedCEK = storeProvider.encryptColumnEncryptionKey(keyAlias, algorithm, plainCEK);
return encryptedCEK;
}
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for (byte b : a)
sb.append(String.format("%02x", b).toUpperCase());
return sb.toString();
}
}
Mengaktifkan Always Encrypted untuk kueri aplikasi
Cara term mudah untuk mengaktifkan enkripsi parameter dan dekripsi hasil kueri kolom terenkripsi adalah dengan mengatur nilai columnEncryptionSetting
kata kunci string koneksi ke Enabled
.
String koneksi berikut adalah contoh mengaktifkan Always Encrypted di driver JDBC:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;user=<user>;encrypt=true;password=<password>;databaseName=<database>;columnEncryptionSetting=Enabled;";
SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);
Kode berikut adalah contoh yang setara untuk menggunakan SQLServerDataSource
objek:
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("<server>");
ds.setPortNumber(<port>);
ds.setUser("<user>");
ds.setPassword("<password>");
ds.setDatabaseName("<database>");
ds.setColumnEncryptionSetting("Enabled");
SQLServerConnection con = (SQLServerConnection) ds.getConnection();
Always Encrypted juga dapat diaktifkan untuk kueri individual. Untuk informasi selengkapnya, lihat Mengontrol dampak performa Always Encrypted. Mengaktifkan Always Encrypted tidak cukup untuk enkripsi atau dekripsi agar berhasil. Anda juga perlu memastikan:
- Aplikasi ini memiliki
VIEW ANY COLUMN MASTER KEY DEFINITION
izin database danVIEW ANY COLUMN ENCRYPTION KEY DEFINITION
, diperlukan untuk mengakses metadata tentang kunci Always Encrypted dalam database. Untuk detailnya, lihat Izin di Always Encrypted (Mesin Database). - Aplikasi dapat mengakses kunci master kolom yang melindungi kunci enkripsi kolom, yang mengenkripsi kolom database yang dikueri. Untuk menggunakan penyedia Java Key Store, Anda perlu memberikan kredensial tambahan di string koneksi. Untuk informasi selengkapnya, lihat Menggunakan penyedia Java Key Store.
Mengonfigurasi cara nilai java.sql.Time dikirim ke server
Properti sendTimeAsDatetime
koneksi digunakan untuk mengonfigurasi bagaimana nilai java.sql.Time dikirim ke server. Ketika diatur ke false, nilai waktu dikirim sebagai jenis waktu SQL Server. Ketika diatur ke true, nilai waktu dikirim sebagai jenis tanggalwaktu. Jika kolom waktu dienkripsi, sendTimeAsDatetime
properti harus false, karena kolom terenkripsi tidak mendukung konversi dari waktu ke tanggalwaktu. Perhatikan juga bahwa properti ini secara default true, jadi untuk menggunakan kolom waktu terenkripsi, atur ke false. Jika tidak, driver akan melemparkan pengecualian. Dimulai dengan driver versi 6.0, SQLServerConnection
kelas memiliki dua metode untuk mengonfigurasi nilai properti ini secara terprogram:
- public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
- boolean publik getSendTimeAsDatetime()
Untuk informasi selengkapnya tentang properti ini, lihat Mengonfigurasi Cara Nilai java.sql.Waktu Dikirim ke Server.
Mengonfigurasi bagaimana nilai String dikirim ke server
Properti sendStringParametersAsUnicode
koneksi digunakan untuk mengonfigurasi bagaimana nilai String dikirim ke SQL Server. Jika diatur ke true, parameter String dikirim ke server dalam format Unicode. Jika diatur ke false, parameter String dikirim dalam format non-Unicode, seperti ASCII atau MBCS, bukan Unicode. Nilai default untuk properti ini adalah true. Ketika Always Encrypted diaktifkan dan char
//varchar
varchar(max)
kolom dienkripsi, nilai sendStringParametersAsUnicode
harus diatur ke false. Jika properti ini diatur ke true, driver akan memberikan pengecualian saat mendekripsi data dari kolom terenkripsi char
//varchar
varchar(max)
yang memiliki karakter Unicode. Untuk informasi selengkapnya tentang properti ini, lihat Mengatur Properti Koneksi.
Penting
Jika sendStringParametersAsUnicode
diatur ke true
dan data unicode dimasukkan ke dalam kolom yang char
/varchar
dienkripsi dengan Always Encrypted, kehilangan data dapat terjadi tanpa kesalahan yang dilaporkan. Kehilangan data hanya dapat terdeteksi saat mencoba mendekripsi data setelah membacanya kembali dari server. Kesalahan seperti Decryption failed. The last 10 bytes of the encrypted column encryption key are: 'C3-D9-10-4E-C1-45-8B-94-A2-43'. The first 10 bytes of ciphertext are: '01-9B-9D-A6-3E-40-22-53-15-9B'.
mungkin hasilnya.
Penting untuk menggunakan jenis data kolom yang benar dan menentukan jenis data yang benar untuk parameter saat menyisipkan data terenkripsi. Jika data unicode diharapkan, gunakan nchar
/nvarchar
kolom dan setNString()
metode. Server tidak dapat melakukan konversi data implisit dan memiliki kemampuan terbatas untuk mendeteksi kesalahan data saat Always Encrypted diaktifkan.
Mengambil dan memodifikasi data dalam kolom terenkripsi
Setelah mengaktifkan Always Encrypted untuk kueri aplikasi, Anda dapat menggunakan API JDBC standar untuk mengambil atau memodifikasi data di kolom database terenkripsi. Jika aplikasi Anda memiliki izin database yang diperlukan dan dapat mengakses kunci master kolom, driver akan mengenkripsi parameter kueri apa pun yang menargetkan kolom terenkripsi, dan mendekripsi data yang diambil dari kolom terenkripsi.
Jika Always Encrypted tidak diaktifkan, kueri dengan parameter yang menargetkan kolom terenkripsi akan gagal. Kueri masih dapat mengambil data dari kolom terenkripsi selama kueri tidak memiliki parameter yang menargetkan kolom terenkripsi. Namun, driver tidak akan mencoba mendekripsi nilai apa pun yang diambil dari kolom terenkripsi dan aplikasi akan menerima data terenkripsi biner (sebagai array byte).
Tabel berikut ini meringkas perilaku kueri tergantung pada apakah Always Encrypted diaktifkan atau tidak:
Karakteristik kueri | Always Encrypted diaktifkan dan aplikasi dapat mengakses kunci dan metadata kunci | Always Encrypted diaktifkan dan aplikasi tidak dapat mengakses kunci atau metadata kunci | Always Encrypted dinonaktifkan |
---|---|---|---|
Kueri dengan parameter yang menargetkan kolom terenkripsi. | Nilai parameter dienkripsi secara transparan. | Kesalahan | Kesalahan |
Kueri mengambil data dari kolom terenkripsi tanpa parameter yang menargetkan kolom terenkripsi. | Hasil dari kolom terenkripsi didekripsi secara transparan. Aplikasi menerima nilai teks biasa dari jenis data JDBC yang sesuai dengan jenis SQL Server yang dikonfigurasi untuk kolom terenkripsi. | Kesalahan | Hasil dari kolom terenkripsi tidak didekripsi. Aplikasi menerima nilai terenkripsi sebagai array byte (byte[]). |
Menyisipkan dan mengambil contoh data terenkripsi
Contoh berikut mengilustrasikan pengambilan dan modifikasi data dalam kolom terenkripsi. Contoh mengasumsikan tabel target dengan skema berikut dan kolom SSN dan BirthDate terenkripsi. Jika Anda telah mengonfigurasi Kunci Master Kolom bernama "MyCMK" dan Kunci Enkripsi Kolom bernama "MyCEK" (seperti yang dijelaskan di bagian penyedia keystore sebelumnya), Anda dapat membuat tabel dengan skrip ini:
CREATE TABLE [dbo].[Patients]([PatientId] [int] IDENTITY(1,1),
[SSN] [char](11) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = MyCEK) NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[BirthDate] [date]
ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = MyCEK) NOT NULL
PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY]);
GO
Untuk setiap contoh kode Java, Anda harus menyisipkan kode khusus keystore di lokasi yang dicatat.
Untuk menggunakan penyedia keystore Azure Key Vault:
String clientID = "<Azure Application ID>";
String clientKey = "<Azure Application API Key Password>";
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
Untuk menggunakan penyedia keystore Windows Certificate Store:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
Untuk menggunakan penyedia keystore Java Key Store:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=<path to jks or pfx file>;keyStoreSecret=<keystore secret/password>";
Menyisipkan contoh data
Contoh ini menyisipkan baris ke dalam tabel Pasien. Perhatikan item berikut:
- Tidak ada yang khusus untuk enkripsi dalam kode sampel. Driver Microsoft JDBC untuk SQL Server secara otomatis mendeteksi dan mengenkripsi parameter yang menargetkan kolom terenkripsi. Perilaku ini membuat enkripsi transparan ke aplikasi.
- Nilai yang disisipkan ke dalam kolom database, termasuk kolom terenkripsi, diteruskan sebagai parameter dengan
SQLServerPreparedStatement
. Meskipun parameter bersifat opsional saat mengirim nilai ke kolom yang tidak dienkripsi (meskipun, sangat disarankan karena membantu mencegah injeksi SQL), diperlukan untuk nilai yang menargetkan kolom terenkripsi. Jika nilai yang disisipkan ke dalam kolom terenkripsi diteruskan sebagai harfiah yang disematkan dalam pernyataan kueri, kueri akan gagal karena driver tidak akan dapat menentukan nilai dalam kolom terenkripsi target dan tidak akan mengenkripsi nilai. Akibatnya, server akan menolaknya sebagai tidak kompatibel dengan kolom terenkripsi. - Semua nilai yang dicetak oleh program akan berada dalam teks biasa, karena Driver Microsoft JDBC untuk SQL Server akan secara transparan mendekripsi data yang diambil dari kolom terenkripsi.
- Jika Anda melakukan pencarian dengan klausa WHERE, nilai yang digunakan dalam klausa WHERE perlu diteruskan sebagai parameter sehingga driver dapat mengenkripsinya secara transparan sebelum mengirimkannya ke database. Dalam contoh berikut, SSN diteruskan sebagai parameter tetapi LastName diteruskan sebagai harfiah karena LastName tidak dienkripsi.
- Metode setter yang digunakan untuk parameter yang menargetkan kolom SSN adalah
setString()
, yang memetakan kechar
/varchar
jenis data SQL Server. Jika untuk parameter ini, metode setter yang digunakan adalahsetNString()
, yang memetakan kenvarchar
nchar
/ , kueri akan gagal, karena Always Encrypted tidak mendukung konversi dari nilai terenkripsi ke nilai terenkripsi.nchar
/nvarchar
char
/varchar
// <Insert keystore-specific code here>
try (Connection sourceConnection = DriverManager.getConnection(connectionUrl);
PreparedStatement insertStatement = sourceConnection.prepareStatement("INSERT INTO [dbo].[Patients] VALUES (?, ?, ?, ?)")) {
insertStatement.setString(1, "795-73-9838");
insertStatement.setString(2, "Catherine");
insertStatement.setString(3, "Abel");
insertStatement.setDate(4, Date.valueOf("1996-09-10"));
insertStatement.executeUpdate();
System.out.println("1 record inserted.\n");
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Mengambil contoh data teks biasa
Contoh berikut menunjukkan pemfilteran data berdasarkan nilai terenkripsi dan mengambil data teks biasa dari kolom terenkripsi. Perhatikan item berikut:
- Nilai yang digunakan dalam klausa WHERE untuk memfilter pada kolom SSN perlu diteruskan sebagai parameter sehingga Driver Microsoft JDBC untuk SQL Server dapat mengenkripsinya secara transparan sebelum mengirimkannya ke database.
- Semua nilai yang dicetak oleh program akan berada di teks biasa, karena Driver Microsoft JDBC untuk SQL Server akan secara transparan mendekripsi data yang diambil dari kolom SSN dan BirthDate.
Catatan
jika kolom dienkripsi dengan enkripsi deterministik, kueri dapat melakukan perbandingan kesetaraan pada kolom tersebut. Untuk informasi selengkapnya, lihat enkripsi deterministik.
// <Insert keystore-specific code here>
try (Connection connection = DriverManager.getConnection(connectionUrl);
PreparedStatement selectStatement = connection
.prepareStatement("\"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN = ?;\"");) {
selectStatement.setString(1, "795-73-9838");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("SSN: " + rs.getString("SSN") + ", FirstName: " + rs.getString("FirstName") + ", LastName:"
+ rs.getString("LastName") + ", Date of Birth: " + rs.getString("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Mengambil contoh data terenkripsi
Jika Always Encrypted tidak diaktifkan, kueri masih dapat mengambil data dari kolom terenkripsi, selama kueri tidak memiliki parameter yang menargetkan kolom terenkripsi.
Contoh berikut mengilustrasikan pengambilan data terenkripsi biner dari kolom terenkripsi. Perhatikan item berikut:
- Karena Always Encrypted tidak diaktifkan dalam string koneksi, kueri akan mengembalikan nilai terenkripsi SSN dan BirthDate sebagai array byte (program mengonversi nilai menjadi string).
- Kueri yang mengambil data dari kolom terenkripsi dengan Always Encrypted dinonaktifkan dapat memiliki parameter, selama tidak ada parameter yang menargetkan kolom terenkripsi. Filter kueri berikut menurut LastName, yang tidak dienkripsi dalam database. Jika kueri difilter oleh SSN atau BirthDate, kueri akan gagal.
try (Connection sourceConnection = DriverManager.getConnection(connectionUrl);
PreparedStatement selectStatement = sourceConnection
.prepareStatement("SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE LastName = ?;");) {
selectStatement.setString(1, "Abel");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("SSN: " + rs.getString("SSN") + ", FirstName: " + rs.getString("FirstName") + ", LastName:"
+ rs.getString("LastName") + ", Date of Birth: " + rs.getString("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Menghindari masalah umum saat mengkueri kolom terenkripsi
Bagian ini menjelaskan kategori kesalahan umum saat mengkueri kolom terenkripsi dari aplikasi Java dan beberapa panduan tentang cara menghindarinya.
Kesalahan konversi jenis data yang tidak didukung
Always Encrypted mendukung beberapa konversi untuk jenis data terenkripsi. Lihat Always Encrypted (Mesin Database) untuk daftar terperinci konversi jenis yang didukung. Inilah yang dapat Anda lakukan untuk menghindari kesalahan konversi jenis data. Pastikan:
Anda menggunakan metode setter yang tepat saat meneruskan nilai untuk parameter yang menargetkan kolom terenkripsi. Pastikan bahwa jenis data SQL Server parameter sama persis dengan jenis kolom target atau konversi jenis data SQL Server dari parameter ke jenis target kolom didukung. Metode API telah ditambahkan ke
SQLServerPreparedStatement
kelas , ,SQLServerCallableStatement
danSQLServerResultSet
untuk meneruskan parameter yang sesuai dengan jenis data SQL Server tertentu. Untuk daftar lengkap API baru, lihat Referensi Always Encrypted API untuk Driver JDBC. Gagal mematuhi definisi jenis data kemungkinan akan mengakibatkan kesalahan bentrokan jenis operand. Berikut ini adalah beberapa contoh penyesuaian yang mungkin diperlukan saat menggunakan Always Encrypted:- Anda dapat menggunakan
setTimestamp()
metode untuk meneruskan parameter ke kolom datetime2 atau datetime yang tidak dienkripsi. Tetapi ketika kolom dienkripsi, Anda harus menggunakan metode yang tepat yang mewakili jenis kolom dalam database. GunakansetTimestamp()
untuk meneruskan nilai ke kolom datetime2 terenkripsi dan gunakansetDateTime()
untuk meneruskan nilai ke kolom tanggalwaktu terenkripsi. - Anda dapat menggunakan
setBinary()
metode untuk meneruskan parameter ke kolom ataubinary
yang tidak dienkripsivarbinary(max)
. Driver default keBINARY
jenis data untuksetBinary()
parameter dan server dapat secara implisit mengonversi data untuk dimasukkan ke dalamvarbinary(max)
kolom. Tetapi ketikavarbinary(max)
kolom dienkripsi, Anda harus menentukan jenis yang lebih tepat untuk data parameter. Contoh:preparedStatement.setObject(1, binaryData, java.sql.JDBCType.LONGVARBINARY)
- Anda dapat menggunakan
presisi dan skala parameter yang menargetkan kolom dari jenis data SQL Server desimal dan numerik sama dengan presisi dan skala yang dikonfigurasi untuk kolom target. Metode API telah ditambahkan ke
SQLServerPreparedStatement
kelas ,SQLServerCallableStatement
, danSQLServerResultSet
untuk menerima presisi dan skala bersama dengan nilai data untuk parameter/kolom yang mewakili jenis data desimal dan numerik. Lihat Referensi API Always Encrypted untuk Driver JDBC untuk daftar lengkap API baru/kelebihan beban.- Misalnya, Saat Anda menggunakan Java
BigDecimal
sebagai jenis parameter yang menargetkan kolom desimal tertentu dalam database, Anda perlu menyediakan presisi dan skala kesetBigDecimal()
metode atausetValue()
metode. Kegagalan untuk menentukan presisi dan skala yang benar dapat mengakibatkan kesalahan seperti berikut ini:
Operand type clash: decimal(18,0) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'myCek', column_encryption_key_database_name = 'issue2169') is incompatible with decimal(20,4) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'myCek', column_encryption_key_database_name = 'myDatabase')
- Misalnya, Saat Anda menggunakan Java
presisi/skala parameter fraksional yang menargetkan kolom
datetime2
, ,datetimeoffset
atau waktu jenis data SQL Server tidak lebih besar dari presisi/skala detik pecahan untuk kolom target dalam kueri yang memodifikasi nilai kolom target. Metode API telah ditambahkan keSQLServerPreparedStatement
kelas ,SQLServerCallableStatement
, danSQLServerResultSet
untuk menerima presisi/skala detik pecahan bersama dengan nilai data untuk parameter yang mewakili jenis data ini. Untuk daftar lengkap API baru/kelebihan beban, lihat Referensi API Always Encrypted untuk Driver JDBC.
Kesalahan karena properti koneksi yang salah
Bagian ini menjelaskan cara mengonfigurasi pengaturan koneksi dengan benar untuk menggunakan data Always Encrypted. Karena jenis data terenkripsi mendukung konversi terbatas, sendTimeAsDatetime
pengaturan koneksi dan sendStringParametersAsUnicode
memerlukan konfigurasi yang tepat untuk menggunakan kolom terenkripsi. Pastikan:
- pengaturan koneksi sendTimeAsDatetime diatur ke false saat menyisipkan data ke dalam kolom waktu terenkripsi. Untuk informasi selengkapnya, lihat Mengonfigurasi cara nilai java.sql.Time dikirim ke server.
- pengaturan koneksi sendStringParametersAsUnicode diatur ke true (atau dibiarkan sebagai default) saat menyisipkan data ke dalam kolom karakter/varchar/varchar(maks) terenkripsi.
Kesalahan karena meneruskan teks biasa alih-alih nilai terenkripsi
Nilai apa pun yang menargetkan kolom terenkripsi perlu dienkripsi di dalam aplikasi. Upaya untuk menyisipkan/memodifikasi atau memfilter berdasarkan nilai teks biasa pada kolom terenkripsi akan mengakibatkan kesalahan yang mirip dengan yang satu ini:
com.microsoft.sqlserver.jdbc.SQLServerException: Operand type clash: varchar is incompatible with varchar(8000) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'MyCEK', column_encryption_key_database_name = 'ae') collation_name = 'SQL_Latin1_General_CP1_CI_AS'
Untuk mencegah kesalahan tersebut, pastikan:
- Always Encrypted diaktifkan untuk kueri aplikasi yang menargetkan kolom terenkripsi (untuk string koneksi atau untuk kueri tertentu).
- Anda menggunakan pernyataan dan parameter yang disiapkan untuk mengirim penargetan data kolom terenkripsi. Contoh berikut menunjukkan kueri yang salah memfilter menurut literal/konstanta pada kolom terenkripsi (SSN), alih-alih meneruskan literal di dalam sebagai parameter. Kueri ini akan gagal:
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM Customers WHERE SSN='795-73-9838'");
Paksa enkripsi pada parameter input
Fitur Enkripsi Paksa memberlakukan enkripsi parameter dengan Always Encrypted. Jika enkripsi paksa digunakan dan SQL Server memberi tahu driver bahwa parameter tidak perlu dienkripsi, kueri yang menggunakan parameter akan gagal. Properti ini memberikan perlindungan tambahan terhadap serangan keamanan yang melibatkan SQL Server yang disusupi yang menyediakan metadata enkripsi yang salah kepada klien, yang dapat menyebabkan pengungkapan data. Metode set* di SQLServerPreparedStatement
kelas dan SQLServerCallableStatement
dan update*
metode di SQLServerResultSet
kelas kelebihan beban untuk menerima argumen boolean untuk menentukan pengaturan enkripsi paksa. Jika nilai argumen ini salah, driver tidak akan memaksa enkripsi pada parameter. Jika enkripsi paksa diatur ke true, parameter kueri hanya dikirim jika kolom tujuan dienkripsi dan Always Encrypted diaktifkan pada koneksi atau pada pernyataan. Properti ini memberikan lapisan keamanan tambahan, memastikan bahwa driver tidak keliru mengirim data ke SQL Server sebagai teks biasa ketika diharapkan untuk dienkripsi.
Untuk informasi selengkapnya tentang SQLServerPreparedStatement
metode dan SQLServerCallableStatement
yang kelebihan beban dengan pengaturan enkripsi paksa, lihat Referensi ALWAYS Encrypted API untuk Driver JDBC
Mengontrol dampak performa Always Encrypted
Karena Always Encrypted adalah teknologi enkripsi sisi klien, sebagian besar overhead performa diamati di sisi klien, bukan dalam database. Selain biaya operasi enkripsi dan dekripsi, sumber overhead performa lainnya di sisi klien adalah:
- Menambahkan perjalanan pulang pergi ke database untuk mengambil metadata untuk parameter kueri.
- Memanggil ke penyimpanan kunci master kolom untuk mengakses kunci master kolom.
Bagian ini menjelaskan pengoptimalan performa bawaan di Microsoft JDBC Driver for SQL Server dan bagaimana Anda dapat mengontrol dampak dari dua faktor yang disebutkan sebelumnya pada performa.
Mengontrol perjalanan pulang pergi untuk mengambil metadata untuk parameter kueri
Jika Always Encrypted diaktifkan untuk koneksi, secara default driver akan memanggil sys.sp_describe_parameter_encryption untuk setiap kueri berparameter, meneruskan pernyataan kueri (tanpa nilai parameter apa pun) ke database. sys.sp_describe_parameter_encryption menganalisis pernyataan kueri untuk mengetahui apakah ada parameter yang perlu dienkripsi, dan jika demikian, untuk masing-masing parameter, ia mengembalikan informasi terkait enkripsi yang memungkinkan driver mengenkripsi nilai parameter. Perilaku ini memastikan tingkat transparansi yang tinggi terhadap aplikasi klien. Selama aplikasi menggunakan parameter untuk meneruskan nilai yang menargetkan kolom terenkripsi ke driver, aplikasi (dan pengembang aplikasi) tidak perlu mengetahui kueri mana yang mengakses kolom terenkripsi.
Mengatur Always Encrypted pada tingkat kueri
Untuk mengontrol dampak performa pengambilan metadata enkripsi untuk kueri berparameter, Anda dapat mengaktifkan Always Encrypted untuk kueri individual alih-alih menyiapkannya untuk koneksi. Dengan cara ini Anda dapat memastikan bahwa sys.sp_describe_parameter_encryption dipanggil hanya untuk kueri yang Anda ketahui memiliki parameter yang menargetkan kolom terenkripsi. Namun, perhatikan bahwa dengan melakukannya Anda mengurangi transparansi enkripsi: jika Anda mengubah properti enkripsi kolom database, Anda mungkin perlu mengubah kode aplikasi Anda untuk menyelaraskannya dengan perubahan skema.
Untuk mengontrol perilaku Always Encrypted dari masing-masing kueri, Anda perlu mengonfigurasi objek pernyataan individual dengan meneruskan Enum, SQLServerStatementColumnEncryptionSetting, yang menentukan bagaimana data akan dikirim dan diterima saat membaca dan menulis kolom terenkripsi untuk pernyataan tertentu tersebut. Berikut adalah beberapa panduan yang berguna:
Jika sebagian besar kueri aplikasi klien mengirimkan kolom terenkripsi akses koneksi database, gunakan panduan berikut:
- Atur
columnEncryptionSetting
kata kunci string koneksi keEnabled
. - Atur
SQLServerStatementColumnEncryptionSetting.Disabled
untuk kueri individual yang tidak mengakses kolom terenkripsi apa pun. Pengaturan ini akan menonaktifkan panggilansys.sp_describe_parameter_encryption
dan mendekripsi nilai apa pun dalam tataan hasil. - Atur
SQLServerStatementColumnEncryptionSetting.ResultSet
untuk kueri individual yang tidak memiliki parameter apa pun yang memerlukan enkripsi tetapi mengambil data dari kolom terenkripsi. Pengaturan ini akan menonaktifkan panggilansys.sp_describe_parameter_encryption
dan enkripsi parameter. Kueri akan mendekripsi hasil dari kolom enkripsi.
- Atur
Jika sebagian besar kueri yang dikirim aplikasi klien melalui koneksi database tidak mengakses kolom terenkripsi, gunakan panduan ini:
- Atur
columnEncryptionSetting
kata kunci string koneksi keDisabled
. - Atur
SQLServerStatementColumnEncryptionSetting.Enabled
untuk kueri individual yang memiliki parameter apa pun yang perlu dienkripsi. Pengaturan ini akan memungkinkan panggilansys.sp_describe_parameter_encryption
dan dekripsi hasil kueri apa pun yang diambil dari kolom terenkripsi. - Atur
SQLServerStatementColumnEncryptionSetting.ResultSet
untuk kueri yang tidak memiliki parameter apa pun yang memerlukan enkripsi tetapi mengambil data dari kolom terenkripsi. Pengaturan ini akan menonaktifkan panggilansys.sp_describe_parameter_encryption
dan enkripsi parameter. Kueri akan mendekripsi hasil dari kolom enkripsi.
- Atur
Pengaturan SQLServerStatementColumnEncryptionSetting
tidak dapat digunakan untuk melewati enkripsi dan mendapatkan akses ke data teks biasa. Untuk informasi selengkapnya tentang cara mengonfigurasi enkripsi kolom pada pernyataan, lihat Referensi ALWAYS Encrypted API untuk Driver JDBC.
Dalam contoh berikut, Always Encrypted dinonaktifkan untuk koneksi database. Kueri masalah aplikasi memiliki parameter yang menargetkan kolom LastName yang tidak dienkripsi. Kueri mengambil data dari kolom SSN dan BirthDate yang keduanya dienkripsi. Dalam kasus seperti itu, panggilan sys.sp_describe_parameter_encryption
untuk mengambil metadata enkripsi tidak diperlukan. Namun, dekripsi hasil kueri perlu diaktifkan sehingga aplikasi dapat menerima nilai teks biasa dari dua kolom terenkripsi. Pengaturan SQLServerStatementColumnEncryptionSetting.ResultSet
digunakan untuk memastikan bahwa.
// Assumes the same table definition as in Section "Retrieving and modifying data in encrypted columns"
// where only SSN and BirthDate columns are encrypted in the database.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<database>;user=<user>;password=<password>;"
+ "keyStoreAuthentication=JavaKeyStorePassword;"
+ "keyStoreLocation=<keyStoreLocation>"
+ "keyStoreSecret=<keyStoreSecret>;";
String filterRecord = "SELECT FirstName, LastName, SSN, BirthDate FROM " + tableName + " WHERE LastName = ?";
try (SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);
PreparedStatement selectStatement = connection.prepareStatement(filterRecord, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
connection.getHoldability(), SQLServerStatementColumnEncryptionSetting.ResultSetOnly);) {
selectStatement.setString(1, "Abel");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("First name: " + rs.getString("FirstName"));
System.out.println("Last name: " + rs.getString("LastName"));
System.out.println("SSN: " + rs.getString("SSN"));
System.out.println("Date of Birth: " + rs.getDate("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Penembolokan metadata parameter kueri
Untuk mengurangi jumlah perjalanan pulang pergi ke database, Driver Microsoft JDBC untuk SQL Server dapat menyimpan informasi terkait enkripsi untuk parameter kueri. Pada versi 11.2.0, informasi terkait enkripsi untuk parameter yang dikembalikan dari panggilan sys.sp_describe_parameter_encryption akan di-cache oleh driver jika proses SQL Server terkait tidak menggunakan enklave aman. Untuk penembolokan dengan penggunaan enklave aman, server harus mendukung pembuatan ulang sesi enklave jika sesi tidak lagi valid.
Penembolokan kunci enkripsi kolom
Untuk mengurangi jumlah panggilan ke penyimpanan kunci master kolom untuk mendekripsi kunci enkripsi kolom, Driver Microsoft JDBC untuk SQL Server menyimpan kunci enkripsi kolom teks biasa dalam memori. Setelah driver menerima nilai kunci enkripsi kolom terenkripsi dari metadata database, driver pertama-tama mencoba menemukan kunci enkripsi kolom teks biasa yang sesuai dengan nilai kunci terenkripsi. Driver memanggil keystore yang berisi kunci master kolom hanya jika tidak dapat menemukan nilai kunci enkripsi kolom terenkripsi di cache.
Anda dapat mengonfigurasi nilai time-to-live untuk entri kunci enkripsi kolom di cache dengan API, setColumnEncryptionKeyCacheTtl()
, di SQLServerConnection
kelas . Nilai time-to-live default untuk entri kunci enkripsi kolom dalam cache adalah dua jam. Untuk menonaktifkan penembolokan, gunakan nilai 0. Untuk mengatur nilai time-to-live apa pun, gunakan API berikut:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (int columnEncryptionKeyCacheTTL, TimeUnit unit)
Misalnya, untuk mengatur nilai time-to-live 10 menit, gunakan:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (10, TimeUnit.MINUTES)
Hanya HARI, JAM, MENIT, atau DETIK yang didukung sebagai unit waktu.
Menyalin data terenkripsi dengan SQLServerBulkCopy
Dengan SQLServerBulkCopy
, Anda dapat menyalin data yang sudah dienkripsi dan disimpan dalam satu tabel ke tabel lain tanpa mendekripsi data. Untuk melakukannya:
- Pastikan konfigurasi enkripsi tabel target identik dengan konfigurasi tabel sumber. Secara khusus, kedua tabel harus memiliki kolom yang sama yang dienkripsi dan kolom harus dienkripsi menggunakan jenis enkripsi yang sama dan kunci enkripsi yang sama. Jika ada kolom target yang dienkripsi secara berbeda dari kolom sumber yang sesuai, Anda tidak akan dapat mendekripsi data dalam tabel target setelah operasi salin. Data akan rusak.
- Konfigurasikan kedua koneksi database ke tabel sumber dan ke tabel target tanpa Always Encrypted diaktifkan.
- Atur
allowEncryptedValueModifications
opsi . Untuk informasi selengkapnya, lihat Menggunakan salinan massal dengan driver JDBC.
Catatan
Berhati-hatilah saat menentukan AllowEncryptedValueModifications
sebagai opsi ini dapat menyebabkan kerusakan database karena Driver Microsoft JDBC untuk SQL Server tidak memeriksa apakah data memang dienkripsi atau apakah data dienkripsi dengan benar dengan jenis enkripsi, algoritma, dan kunci yang sama dengan kolom target.