Menggunakan Always Encrypted dengan Penyedia Data .NET Framework untuk SQL Server

Berlaku untuk:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Artikel ini menyediakan informasi tentang cara mengembangkan aplikasi .NET Framework menggunakan Always Encrypted atau Always Encrypted dengan enklave aman dan Penyedia Data .NET Framework untuk SQL Server (System.Data.SqlClient).

Catatan

Menggunakan Penyedia Data .NET Framework untuk SQL Server (System.Data.SqlClient) tidak disarankan untuk pengembangan baru. Untuk informasi selengkapnya, lihat System.Data.SqlClient.

Always Encrypted memungkinkan aplikasi 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 Penyedia Data .NET Framework untuk SQL Server, mencapainya dengan mengenkripsi dan mendekripsi data sensitif secara transparan di aplikasi klien. Driver secara otomatis menentukan parameter kueri mana yang sesuai dengan kolom database sensitif (dilindungi menggunakan Always Encrypted), dan mengenkripsi nilai parameter tersebut sebelum meneruskan data ke SQL Server atau Azure SQL Database. Demikian pula, driver secara transparan mendekripsi data yang diambil dari kolom database terenkripsi dalam hasil kueri. Untuk informasi selengkapnya, lihat Mengembangkan aplikasi menggunakan Always Encrypted dan Mengembangkan aplikasi menggunakan Always Encrypted dengan enklave aman.

Catatan

Penyedia Data .NET Framework untuk SQL Server (System.Data.SqlClient) tidak mendukung penggunaan enklave VBS tanpa pengesahan.

Prasyarat

  • Konfigurasikan Always Encrypted di database Anda. Ini melibatkan penyediaan kunci Always Encrypted dan menyiapkan enkripsi untuk kolom database yang dipilih. Jika Anda belum memiliki database dengan Always Encrypted yang dikonfigurasi, ikuti petunjuk dalam Tutorial: Memulai Always Encrypted.
  • Jika Anda menggunakan Always Encrypted dengan enklave aman, lihat Mengembangkan aplikasi menggunakan Always Encrypted dengan enklave aman untuk prasyarat lainnya.
  • Pastikan .NET Framework versi 4.6.1 atau yang lebih tinggi diinstal pada komputer pengembangan Anda. Untuk detailnya, lihat .NET Framework 4.6. Anda juga perlu memastikan .NET Framework versi 4.6 atau yang lebih tinggi dikonfigurasi sebagai versi .NET Framework target di lingkungan pengembangan Anda. Jika Anda menggunakan Visual Studio, lihat Cara: Menargetkan Versi .NET Framework.

Catatan

Tingkat dukungan untuk Always Encrypted dalam versi .NET Framework tertentu bervariasi. Referensi Always Encrypted API tercantum di bagian berikut.

Mengaktifkan Always Encrypted untuk kueri aplikasi

Cara term mudah untuk mengaktifkan enkripsi parameter, dan dekripsi hasil kueri yang menargetkan kolom terenkripsi, adalah dengan mengatur nilai kata kunci string koneksi Pengaturan Enkripsi Kolom untuk diaktifkan.

Berikut ini adalah contoh string koneksi yang mengaktifkan Always Encrypted:

string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true; Column Encryption Setting=enabled";
SqlConnection connection = new SqlConnection(connectionString);

Berikut ini adalah contoh yang setara menggunakan Properti SqlConnectionStringBuilder.ColumnEncryptionSetting.

SqlConnectionStringBuilder strbldr = new SqlConnectionStringBuilder();
strbldr.DataSource = "server63";
strbldr.InitialCatalog = "Clinic";
strbldr.IntegratedSecurity = true;
strbldr.ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Enabled;
SqlConnection connection = new SqlConnection(strbldr.ConnectionString);

Always Encrypted juga dapat diaktifkan untuk kueri individual. Lihat bagian Mengontrol dampak performa Always Encrypted di bawah ini. Mengaktifkan Always Encrypted tidak cukup untuk enkripsi atau dekripsi agar berhasil. Anda juga perlu memastikan:

  • Aplikasi ini memiliki izin database VIEW ANY COLUMN MASTER KEY DEFINITION dan VIEW ANY COLUMN ENCRYPTION KEY DEFINITION , yang diperlukan untuk mengakses metadata tentang kunci Always Encrypted dalam database. Untuk detailnya, lihat bagian Izin di Always Encrypted (Mesin Database).
  • Aplikasi dapat mengakses kunci master kolom yang melindungi kunci enkripsi kolom, mengenkripsi kolom database yang dikueri.

Mengaktifkan Always Encrypted dengan enklave aman

Dimulai dengan .NET Framework versi 4.7.2, driver mendukung Always Encrypted dengan enklave aman.

Untuk informasi umum tentang peran driver klien dalam komputasi enklave dan pengesahan enklave, lihat Mengembangkan aplikasi menggunakan Always Encrypted dengan enklave aman.

Untuk mengonfigurasi aplikasi Anda:

  1. Aktifkan Always Encrypted untuk kueri aplikasi Anda, seperti yang dijelaskan di bagian sebelumnya.

  2. Integrasikan paket NuGet Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders dengan aplikasi Anda. NuGet adalah pustaka penyedia enklave, menerapkan logika sisi klien untuk protokol pengesahan dan untuk membuat saluran aman dengan enklave yang aman.

  3. Perbarui konfigurasi aplikasi Anda (misalnya di web.config atau app.config) untuk menentukan pemetaan antara jenis enklave, yang dikonfigurasi untuk database Anda, dan penyedia enklave.

    1. Jika Anda menggunakan SQL Server dan Host Guardian Service (HGS), Anda perlu memetakan jenis enklave VBS ke kelas Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.HostGuardianServiceEnclaveProvider dari paket NuGet.
    2. Jika Anda menggunakan Azure SQL Database dan Microsoft Azure Attestation, Anda perlu memetakan jenis enklave SGX ke kelas Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.AzureAttestationEnclaveProvider dari paket NuGet.

    Untuk petunjuk terperinci tentang cara mengedit konfigurasi aplikasi Anda, lihat Tutorial: Mengembangkan aplikasi .NET Framework menggunakan Always Encrypted dengan enklave aman.

  4. Atur Enclave Attestation URL kata kunci dalam string koneksi database Anda ke URL pengesahan (titik akhir layanan pengesahan). Anda perlu mendapatkan URL pengesahan untuk lingkungan Anda dari administrator layanan pengesahan Anda.

    1. Jika Anda menggunakan SQL Server dan Host Guardian Service (HGS), lihat Menentukan dan membagikan URL pengesahan HGS.
    2. Jika Anda menggunakan Azure SQL Database dan Microsoft Azure Attestation, lihat Menentukan URL pengesahan untuk kebijakan pengesahan Anda.

Untuk tutorial langkah demi langkah, lihat Tutorial: Mengembangkan aplikasi .NET Framework menggunakan Always Encrypted dengan enklave aman

Mengambil dan memodifikasi data dalam kolom terenkripsi

Setelah mengaktifkan Always Encrypted untuk kueri aplikasi, Anda dapat menggunakan API ADO.NET standar (lihat Mengambil dan Memodifikasi Data dalam ADO.NET) atau Penyedia Data .NET Framework untuk API SQL Server , yang ditentukan dalam Namespace Layanan System.Data.SqlClient, untuk mengambil atau memodifikasi data dalam kolom database terenkripsi. Dengan asumsi aplikasi Anda memiliki izin database yang diperlukan dan dapat mengakses kunci master kolom, Penyedia Data .NET Framework untuk SQL Server akan mengenkripsi parameter kueri apa pun yang menargetkan kolom terenkripsi, dan akan mendekripsi data yang diambil dari kolom terenkripsi yang mengembalikan nilai teks biasa jenis .NET, yang sesuai dengan jenis data SQL Server yang ditetapkan untuk kolom dalam skema database. 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, Penyedia Data .NET Framework untuk SQL Server tidak akan mencoba mendekripsi nilai apa pun yang diambil dari kolom terenkripsi dan aplikasi akan menerima data terenkripsi biner (sebagai array byte).

Tabel di bawah 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 tipe data .NET 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[]).

Contoh berikut mengilustrasikan pengambilan dan modifikasi data dalam kolom terenkripsi. Contoh mengasumsikan tabel target dengan skema di bawah ini. Kolom SSN dan BirthDate dienkripsi.

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 = CEK1) 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 = CEK1) NOT NULL
 PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY])
 GO

Menyisipkan contoh data

Contoh ini menyisipkan baris ke dalam tabel Pasien. Perhatikan hal-hal berikut:

  • Tidak ada yang khusus untuk enkripsi dalam kode sampel. Penyedia Data .NET Framework untuk SQL Server secara otomatis mendeteksi dan mengenkripsi parameter paramSSN dan paramBirthdate yang menargetkan kolom terenkripsi. Ini membuat enkripsi transparan ke aplikasi.
  • Nilai yang disisipkan ke dalam kolom database, termasuk kolom terenkripsi, diteruskan sebagai objek SqlParameter . Saat menggunakan SqlParameter 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 dalam kolom SSN atau BirthDate diteruskan sebagai harfiah yang disematkan dalam pernyataan kueri, kueri akan gagal karena Penyedia Data .NET Framework untuk SQL Server tidak akan dapat menentukan nilai dalam kolom terenkripsi target, sehingga tidak akan mengenkripsi nilai. Akibatnya, server akan menolaknya sebagai tidak kompatibel dengan kolom terenkripsi.
  • Jenis data parameter yang menargetkan kolom SSN diatur ke string ANSI (non-Unicode), yang memetakan ke jenis data char/varchar SQL Server. Jika jenis parameter diatur ke string Unicode (String), yang memetakan ke nchar/nvarchar, kueri akan gagal, karena Always Encrypted tidak mendukung konversi dari nilai nchar/nvarchar terenkripsi ke nilai char/varchar terenkripsi. Lihat Pemetaan Tipe Data SQL Server untuk informasi tentang pemetaan jenis data.
  • Jenis data parameter yang dimasukkan ke dalam kolom BirthDate secara eksplisit diatur ke jenis data SQL Server target menggunakan Properti SqlParameter.SqlDbType, alih-alih mengandalkan pemetaan implisit jenis .NET ke jenis data SQL Server yang diterapkan saat menggunakan Properti SqlParameter.DbType. Secara default, Struktur DateTime memetakan ke jenis data SQL Server tanggalwaktu. Karena jenis data kolom BirthDate adalah tanggal dan Always Encrypted tidak mendukung konversi nilai tanggalwaktu terenkripsi ke nilai tanggal terenkripsi, menggunakan pemetaan default akan mengakibatkan kesalahan.
string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true; Column Encryption Setting=enabled";
using (SqlConnection connection = new SqlConnection(strbldr.ConnectionString))
{
   using (SqlCommand cmd = connection.CreateCommand())
   {
      cmd.CommandText = @"INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (@SSN, @FirstName, @LastName, @BirthDate);";

      SqlParameter paramSSN = cmd.CreateParameter();
      paramSSN.ParameterName = @"@SSN";
      paramSSN.DbType = DbType.AnsiStringFixedLength;
      paramSSN.Direction = ParameterDirection.Input;
      paramSSN.Value = "795-73-9838";
      paramSSN.Size = 11;
      cmd.Parameters.Add(paramSSN);

      SqlParameter paramFirstName = cmd.CreateParameter();
      paramFirstName.ParameterName = @"@FirstName";
      paramFirstName.DbType = DbType.String;
      paramFirstName.Direction = ParameterDirection.Input;
      paramFirstName.Value = "Catherine";
      paramFirstName.Size = 50;
      cmd.Parameters.Add(paramFirstName);

      SqlParameter paramLastName = cmd.CreateParameter();
      paramLastName.ParameterName = @"@LastName";
      paramLastName.DbType = DbType.String;
      paramLastName.Direction = ParameterDirection.Input;
      paramLastName.Value = "Abel";
      paramLastName.Size = 50;
      cmd.Parameters.Add(paramLastName);

      SqlParameter paramBirthdate = cmd.CreateParameter();
      paramBirthdate.ParameterName = @"@BirthDate";
      paramBirthdate.SqlDbType = SqlDbType.Date;
      paramBirthdate.Direction = ParameterDirection.Input;
      paramBirthdate.Value = new DateTime(1996, 09, 10);
      cmd.Parameters.Add(paramBirthdate);

      cmd.ExecuteNonQuery();
   } 
}

Mengambil Contoh data teks biasa

Contoh berikut menunjukkan pemfilteran data berdasarkan nilai terenkripsi, dan mengambil data teks biasa dari kolom terenkripsi. Perhatikan hal-hal berikut:

  • Nilai yang digunakan dalam klausul WHERE untuk memfilter pada kolom SSN perlu diteruskan menggunakan SqlParameter, sehingga Penyedia Data .NET Framework untuk SQL Server dapat mengenkripsinya secara transparan sebelum mengirimkannya ke database.
  • Semua nilai yang dicetak oleh program akan berada dalam teks biasa, karena Penyedia Data .NET Framework untuk SQL Server akan secara transparan mendekripsi data yang diambil dari kolom SSN dan BirthDate.

Catatan

Kueri dapat melakukan perbandingan kesetaraan pada kolom jika dienkripsi menggunakan enkripsi deterministik. Untuk informasi selengkapnya, lihat Memilih Enkripsi Deterministik atau Acak.

string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true; Column Encryption Setting=enabled";
    
using (SqlConnection connection = new SqlConnection(strbldr.ConnectionString))
 {
    using (SqlCommand cmd = connection.CreateCommand())
 {

 cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN=@SSN";
 SqlParameter paramSSN = cmd.CreateParameter();
 paramSSN.ParameterName = @"@SSN";
 paramSSN.DbType = DbType.AnsiStringFixedLength;
 paramSSN.Direction = ParameterDirection.Input;
 paramSSN.Value = "795-73-9838";
 paramSSN.Size = 11;
 cmd.Parameters.Add(paramSSN);
 using (SqlDataReader reader = cmd.ExecuteReader())
 {
   if (reader.HasRows)
 {
 while (reader.Read())
 {
    Console.WriteLine(@"{0}, {1}, {2}, {3}", reader[0], reader[1], reader[2], ((DateTime)reader[3]).ToShortDateString());
 }

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 menunjukkan cara mengambil data terenkripsi biner dari kolom terenkripsi. Perhatikan hal-hal 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 di atas menurut LastName, yang tidak dienkripsi dalam database. Jika kueri difilter oleh SSN atau BirthDate, kueri akan gagal.
string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true";
                
using (SqlConnection connection = new SqlConnection(connectionString))
{
   connection.Open();
   using (SqlCommand cmd = connection.CreateCommand())
   {
      cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [LastName]=@LastName";
      SqlParameter paramLastName = cmd.CreateParameter();
      paramLastName.ParameterName = @"@LastName";
      paramLastName.DbType = DbType.String;
      paramLastName.Direction = ParameterDirection.Input;
      paramLastName.Value = "Abel";
      paramLastName.Size = 50;
      cmd.Parameters.Add(paramLastName);
      using (SqlDataReader reader = cmd.ExecuteReader())
      {
         if (reader.HasRows)
         {
            while (reader.Read())
         {
         Console.WriteLine(@"{0}, {1}, {2}, {3}", BitConverter.ToString((byte[])reader[0]), reader[1], reader[2], BitConverter.ToString((byte[])reader[3]));
      }
   }
}

Menghindari masalah umum saat mengkueri kolom terenkripsi

Bagian ini menjelaskan kategori kesalahan umum saat mengkueri kolom terenkripsi dari aplikasi .NET 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 untuk daftar terperinci konversi jenis yang didukung. Lakukan hal berikut untuk menghindari kesalahan konversi jenis data:

  • Atur jenis parameter yang menargetkan kolom terenkripsi, sehingga jenis data SQL Server parameter sama persis dengan jenis kolom target, atau konversi jenis data SQL Server dari parameter ke jenis target kolom didukung. Anda dapat menerapkan pemetaan jenis data .NET yang diinginkan ke jenis data SQL Server tertentu dengan menggunakan Properti SqlParameter.SqlDbType.
  • Verifikasi 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.
  • Verifikasi presisi parameter yang menargetkan kolom jenis data datetime2, datetimeoffset, atau time SQL Server tidak lebih besar dari presisi untuk kolom target (dalam kueri yang memodifikasi nilai di kolom target).

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 ini:

System.Data.SqlClient.SqlException (0x80131904): 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 = 'CEK_Auto1', column_encryption_key_database_name = 'Clinic') 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 di objek SqlCommand untuk kueri tertentu).
  • Anda menggunakan SqlParameter untuk mengirim data yang menargetkan kolom terenkripsi. Contoh berikut menunjukkan kueri yang salah memfilter menurut literal/konstanta pada kolom terenkripsi (SSN)(alih-alih meneruskan literal di dalam objek SqlParameter).
using (SqlCommand cmd = connection.CreateCommand())
{
   cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN='795-73-9838'";
cmd.ExecuteNonQuery();
}

Bekerja dengan penyimpanan Kunci Master Kolom

Untuk mengenkripsi nilai parameter atau untuk mendekripsi data dalam hasil kueri, Penyedia Data .NET Framework untuk SQL Server perlu mendapatkan kunci enkripsi kolom yang dikonfigurasi untuk kolom target. 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 menyimpan kunci master kolom, dan hanya berisi informasi tentang penyimpanan kunci yang berisi kunci master kolom tertentu dan lokasi kunci di penyimpanan kunci.

Untuk mendapatkan nilai teks biasa dari kunci enkripsi kolom, Penyedia Data .NET Framework untuk SQL Server terlebih dahulu mendapatkan metadata tentang kunci enkripsi kolom dan kunci master kolom yang sesuai, lalu menggunakan informasi dalam metadata untuk menghubungi penyimpanan kunci, yang berisi kunci master kolom, dan untuk mendekripsi kunci enkripsi kolom terenkripsi. Penyedia Data .NET Framework untuk SQL Server berkomunikasi dengan penyimpanan kunci menggunakan penyedia penyimpanan kunci master kolom - yang merupakan instans kelas yang berasal dari Kelas SqlColumnEncryptionKeyStoreProvider.

Proses untuk mendapatkan kunci enkripsi kolom:

  1. Jika Always Encrypted diaktifkan untuk kueri, Penyedia Data .NET Framework untuk SQL Server secara transparan memanggil sys.sp_describe_parameter_encryption untuk mengambil metadata enkripsi untuk parameter yang menargetkan kolom terenkripsi, jika kueri memiliki parameter. Untuk data terenkripsi yang terkandung dalam hasil kueri, SQL Server secara otomatis melampirkan metadata enkripsi. Informasi tentang kunci master kolom meliputi:

    • Nama penyedia penyimpanan kunci yang merangkum penyimpanan kunci yang berisi kunci master kolom.
    • Jalur kunci yang menentukan lokasi kunci master kolom di penyimpanan kunci.

    Informasi tentang kunci enkripsi kolom meliputi:

    • Nilai terenkripsi kunci enkripsi kolom.
    • Nama algoritma yang digunakan untuk mengenkripsi kunci enkripsi kolom.
  2. Penyedia Data .NET Framework untuk SQL Server menggunakan nama penyedia penyimpanan kunci master kolom untuk mencari objek penyedia (instans kelas yang berasal dari SqlColumnEncryptionKeyStoreProvider Class) dalam struktur data internal.

  3. Untuk mendekripsi kunci enkripsi kolom, Penyedia Data .NET Framework untuk SQL Server memanggil Metode SqlColumnEncryptionKeyStoreProvider.DecryptColumnEncryptionKey, melewati jalur kunci master kolom, nilai terenkripsi kunci enkripsi kolom dan nama algoritma enkripsi, digunakan untuk menghasilkan kunci enkripsi kolom terenkripsi.

Menggunakan penyedia penyimpanan kunci master kolom bawaan

Penyedia Data .NET Framework untuk SQL Server dilengkapi dengan penyedia penyimpanan kunci master kolom bawaan berikut, yang telah terdaftar sebelumnya dengan nama penyedia tertentu (digunakan untuk mencari penyedia).

Kelas Deskripsi Nama penyedia (pencarian)
Kelas SqlColumnEncryptionCertificateStoreProvider Penyedia untuk Windows Certificate Store. MSSQL_CERTIFICATE_STORE
Kelas SqlColumnEncryptionCngProvider

Catatan: penyedia ini tersedia di .NET Framework 4.6.1 dan versi yang lebih baru.
Penyedia untuk penyimpanan kunci yang mendukung MICROSOFT Cryptography API: Next Generation (CNG) API. Biasanya, penyimpanan jenis ini adalah modul keamanan perangkat keras - perangkat fisik yang melindungi dan mengelola kunci digital dan menyediakan pemrosesan kripto. MSSQL_CNG_STORE
Kelas SqlColumnEncryptionCspProvider

Catatan: penyedia ini tersedia di .NET Framework 4.6.1 atau versi yang lebih baru.
Penyedia untuk penyimpanan kunci yang mendukung Microsoft Cryptography API (CAPI). Biasanya, penyimpanan jenis ini adalah modul keamanan perangkat keras - perangkat fisik yang melindungi dan mengelola kunci digital dan menyediakan pemrosesan kripto. MSSQL_CSP_PROVIDER

Anda tidak perlu membuat perubahan kode aplikasi apa pun untuk menggunakan penyedia ini tetapi perhatikan hal berikut:

  • Anda (atau DBA Anda) perlu memastikan nama penyedia, dikonfigurasi dalam metadata kunci master kolom, sudah benar dan jalur kunci master kolom mematuhi format jalur kunci yang valid untuk penyedia tertentu. Disarankan agar Anda mengonfigurasi kunci menggunakan alat seperti SQL Server Management Studio, yang secara otomatis menghasilkan nama penyedia dan jalur kunci yang valid saat mengeluarkan pernyataan CREATE COLUMN MASTER KEY (Transact-SQL). Untuk informasi selengkapnya, lihat Mengonfigurasi Always Encrypted menggunakan SQL Server Management Studio dan Mengonfigurasi Always Encrypted menggunakan PowerShell.
  • Pastikan aplikasi Anda dapat mengakses kunci di penyimpanan kunci. Ini mungkin melibatkan pemberian akses aplikasi Anda ke kunci dan/atau penyimpanan kunci, tergantung pada penyimpanan kunci, atau melakukan langkah-langkah konfigurasi khusus penyimpanan kunci lainnya. Misalnya, untuk mengakses penyimpanan kunci yang mengimplementasikan CNG atau CAPI (misalnya, modul keamanan perangkat keras), Anda perlu memastikan pustaka yang menerapkan CNG atau CAPI untuk penyimpanan Anda diinstal di komputer aplikasi Anda. Untuk detailnya, lihat Membuat dan menyimpan kunci master kolom untuk Always Encrypted.

Menggunakan penyedia Azure Key Vault

Azure Key Vault adalah opsi yang mudah untuk menyimpan dan mengelola kunci master kolom untuk Always Encrypted (terutama jika aplikasi Anda dihosting di Azure). Penyedia Data .NET Framework untuk SQL Server tidak menyertakan penyedia penyimpanan kunci master kolom bawaan untuk Azure Key Vault, tetapi tersedia sebagai paket NuGet, yang dapat dengan mudah Anda integrasikan dengan aplikasi Anda. Untuk detailnya, lihat:

Menerapkan penyedia penyimpanan kunci master kolom kustom

Jika Anda ingin menyimpan kunci master kolom di penyimpanan kunci yang tidak didukung oleh penyedia yang ada, Anda dapat menerapkan penyedia kustom dengan memperluas Kelas SqlColumnEncryptionCngProvider dan mendaftarkan penyedia menggunakan metode SqlConnection.RegisterColumnEncryptionKeyStoreProviders.

public class MyCustomKeyStoreProvider : SqlColumnEncryptionKeyStoreProvider
    {
        public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey)
        {
            // Logic for encrypting a column encrypted key.
        }
        public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] EncryptedColumnEncryptionKey)
        {
            // Logic for decrypting a column encrypted key.
        }
    }  
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary\<string, SqlColumnEncryptionKeyStoreProvider> providers =
               new Dictionary\<string, SqlColumnEncryptionKeyStoreProvider>();
            providers.Add("MY_CUSTOM_STORE", customProvider);
            SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
            providers.Add(SqlColumnEncryptionCertificateStoreProvider.ProviderName, customProvider);
            SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers); 
	   // ...
        }

    }

Menggunakan penyedia penyimpanan kunci master kolom untuk provisi kunci terprogram

Saat mengakses kolom terenkripsi, Penyedia Data .NET Framework 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 eksplisit untuk memprovisikan dan mengelola kunci Always Encrypted secara terprogram: untuk menghasilkan kunci enkripsi kolom terenkripsi dan mendekripsi kunci enkripsi kolom (misalnya, sebagai rotasi kunci master kolom bagian). Untuk informasi selengkapnya, lihat Gambaran Umum manajemen kunci untuk Always Encrypted. Menerapkan alat manajemen kunci Anda sendiri mungkin diperlukan hanya jika Anda menggunakan penyedia penyimpanan kunci kustom. Saat menggunakan kunci yang disimpan di penyimpanan kunci, penyedia bawaan mana yang ada, dan atau di Azure Key Vault, Anda dapat menggunakan alat yang ada, seperti SQL Server Management Studio atau PowerShell, untuk mengelola dan menyediakan kunci. Contoh di bawah ini, menggambarkan pembuatan kunci enkripsi kolom dan menggunakan Kelas SqlColumnEncryptionCertificateStoreProvider untuk mengenkripsi kunci dengan sertifikat.

using System.Security.Cryptography;
static void Main(string[] args)
{
    byte[] EncryptedColumnEncryptionKey = GetEncryptedColumnEncryptonKey(); 
    Console.WriteLine("0x" + BitConverter.ToString(EncryptedColumnEncryptionKey).Replace("-", "")); 
    Console.ReadKey();
}

static byte[]  GetEncryptedColumnEncryptonKey()
{
    int cekLength = 32;
    String certificateStoreLocation = "CurrentUser";
    String certificateThumbprint = "698C7F8E21B2158E9AED4978ADB147CF66574180";
    // Generate the plaintext column encryption key.
    byte[] columnEncryptionKey = new byte[cekLength];
    RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
    rngCsp.GetBytes(columnEncryptionKey);

    // Encrypt the column encryption key with a certificate.
    string keyPath = String.Format(@"{0}/My/{1}", certificateStoreLocation, certificateThumbprint);
    SqlColumnEncryptionCertificateStoreProvider provider = new SqlColumnEncryptionCertificateStoreProvider();
    return provider.EncryptColumnEncryptionKey(keyPath, @"RSA_OAEP", columnEncryptionKey); 
}

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:

  • Perjalanan pulang pergi ekstra 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 Penyedia .NET Framework untuk SQL Server dan bagaimana Anda dapat mengontrol dampak dari dua faktor di atas pada performa.

Mengontrol perjalanan pulang pergi untuk mengambil metadata untuk parameter kueri

Jika Always Encrypted diaktifkan untuk koneksi, secara default, Penyedia Data .NET Framework untuk SQL Server akan memanggil sys.sp_describe_parameter_encryption untuk setiap kueri berparameter, meneruskan pernyataan kueri (tanpa nilai parameter apa pun) ke SQL Server. sys.sp_describe_parameter_encryption menganalisis pernyataan kueri untuk mencari tahu apakah ada parameter yang perlu dienkripsi, dan jika demikian, untuk setiap hal tersebut, ia mengembalikan informasi terkait enkripsi yang akan memungkinkan Penyedia Data .NET Framework untuk SQL Server mengenkripsi nilai parameter. Perilaku di atas memastikan tingkat transparansi yang tinggi terhadap aplikasi klien. Aplikasi (dan pengembang aplikasi) tidak perlu mengetahui kueri mana yang mengakses kolom terenkripsi, selama nilai yang menargetkan kolom terenkripsi diteruskan ke Penyedia Data .NET Framework untuk SQL Server di objek SqlParameter.

Penembolokan metadata kueri

Di .NET Framework 4.6.2 dan yang lebih baru, Penyedia Data .NET Framework untuk SQL Server menyimpan hasil sys.sp_describe_parameter_encryption untuk setiap pernyataan kueri. Jadi, jika pernyataan kueri yang sama dijalankan beberapa kali, driver memanggil sys.sp_describe_parameter_encryption hanya sekali. Penembolokan metadata enkripsi untuk pernyataan kueri secara substansial mengurangi biaya performa pengambilan metadata dari database. Penembolokan diaktifkan secara default. Anda dapat menonaktifkan penembolokan metadata parameter dengan mengatur Properti SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled ke false, tetapi melakukannya tidak disarankan kecuali dalam kasus yang jarang terjadi seperti yang dijelaskan di bawah ini:

Pertimbangkan database yang memiliki dua skema berbeda: s1 dan s2. Setiap skema berisi tabel dengan nama yang sama: t. Definisi s1.t tabel dan s2.t identik, kecuali properti terkait enkripsi: Kolom, bernama c, tidak dienkripsi, dan dienkripsi s1.t di s2.t. Database memiliki dua pengguna: u1 dan u2. Skema default untuk u1 pengguna adalah s1. Skema default untuk u2 adalah s2. Aplikasi .NET membuka dua koneksi ke database, meniru u1 pengguna pada satu koneksi, dan u2 pengguna pada koneksi lain. Aplikasi mengirim kueri dengan parameter yang menargetkan c kolom melalui koneksi untuk pengguna u1 (kueri tidak menentukan skema, sehingga skema pengguna default diasumsikan). Selanjutnya, aplikasi mengirimkan kueri yang sama melalui koneksi untuk u2 pengguna. Jika penembolokan metadata kueri diaktifkan, setelah kueri pertama, cache akan diisi dengan metadata yang menunjukkan c kolom, target parameter kueri tidak dienkripsi. Karena kueri kedua memiliki pernyataan kueri yang identik, informasi yang disimpan dalam cache akan digunakan. Akibatnya, driver akan mengirim kueri tanpa mengenkripsi parameter (yang salah, karena kolom target, s2.t.c dienkripsi), membocorkan nilai teks biasa parameter ke server. Server akan mendeteksi ketidaksesuaian itu dan akan memaksa driver untuk menyegarkan cache, sehingga aplikasi akan secara transparan mengirim ulang kueri dengan nilai parameter yang dienkripsi dengan benar. Dalam kasus seperti itu, penembolokan harus dinonaktifkan untuk mencegah kebocoran nilai sensitif ke server.

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 hanya dipanggil 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.

Catatan

Mengatur Always Encrypted pada tingkat kueri memiliki manfaat performa terbatas dalam .NET 4.6.2 dan versi yang lebih baru, yang menerapkan penembolokan metadata enkripsi parameter.

Untuk mengontrol perilaku Always Encrypted dari masing-masing kueri, Anda perlu menggunakan konstruktor SqlCommand dan SqlCommandColumnEncryptionSetting ini. Berikut adalah beberapa panduan yang berguna:

  • Jika sebagian besar kueri aplikasi klien mengirim melalui kolom terenkripsi akses koneksi database:
    • Atur kata kunci string koneksi Pengaturan Enkripsi Kolom ke Diaktifkan.
    • Atur SqlCommandColumnEncryptionSetting.Disabled untuk kueri individual yang tidak mengakses kolom terenkripsi apa pun. Ini akan menonaktifkan panggilan sys.sp_describe_parameter_encryption serta upaya untuk mendekripsi nilai apa pun dalam tataan hasil.
    • Atur SqlCommandColumnEncryptionSetting.ResultSet untuk kueri individual yang tidak memiliki parameter apa pun yang memerlukan enkripsi, tetapi mengambil data dari kolom terenkripsi. Ini akan menonaktifkan panggilan sys.sp_describe_parameter_encryption dan enkripsi parameter. Kueri akan dapat mendekripsi hasil dari kolom enkripsi.
  • Jika sebagian besar kueri yang dikirim aplikasi klien melalui koneksi database tidak mengakses kolom terenkripsi:
    • Atur kata kunci string koneksi Pengaturan Enkripsi Kolom ke Dinonaktifkan.
    • Atur SqlCommandColumnEncryptionSetting.Enabled untuk kueri individual yang memiliki parameter apa pun yang perlu dienkripsi. Ini akan memungkinkan panggilan sys.sp_describe_parameter_encryption serta dekripsi hasil kueri apa pun yang diambil dari kolom terenkripsi.
    • Atur SqlCommandColumnEncryptionSetting.ResultSet untuk kueri yang tidak memiliki parameter apa pun yang memerlukan enkripsi, tetapi mengambil data dari kolom terenkripsi. Ini akan menonaktifkan panggilan sys.sp_describe_parameter_encryption dan enkripsi parameter. Kueri akan dapat mendekripsi hasil dari kolom enkripsi.

Dalam contoh di bawah ini, Always Encrypted dinonaktifkan untuk koneksi database. Kueri bahwa 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, memanggil 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 SqlCommandColumnEncryptionSetting.ResultSet digunakan untuk memastikannya.

string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    using (SqlCommand cmd = new SqlCommand(@"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [LastName]=@LastName",
connection, null, SqlCommandColumnEncryptionSetting.ResultSetOnly))
    {
        SqlParameter paramLastName = cmd.CreateParameter();
        paramLastName.ParameterName = @"@LastName";
        paramLastName.DbType = DbType.String;
        paramLastName.Direction = ParameterDirection.Input;
        paramLastName.Value = "Abel";
        paramLastName.Size = 50;
        cmd.Parameters.Add(paramLastName);
        using (SqlDataReader reader = cmd.ExecuteReader())
            {
               if (reader.HasRows)
               {
                  while (reader.Read())
                  {
                     Console.WriteLine(@"{0}, {1}, {2}, {3}", reader[0], reader[1], reader[2], ((DateTime)reader[3]).ToShortDateString());
                  }
               }
            }
  } 
}

Penembolokan kunci enkripsi kolom

Untuk mengurangi jumlah panggilan ke penyimpanan kunci master kolom untuk mendekripsi kunci enkripsi kolom, Penyedia Data .NET Framework untuk SQL Server menyimpan kunci enkripsi kolom teks biasa dalam memori. Setelah 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 penyimpanan kunci yang berisi kunci master kolom, hanya jika tidak dapat menemukan nilai kunci enkripsi kolom terenkripsi di cache.

Catatan

Dalam .NET Framework 4.6 dan 4.6.1, entri kunci enkripsi kolom dalam cache tidak pernah dikeluarkan. Ini berarti bahwa untuk kunci enkripsi kolom terenkripsi tertentu, driver menghubungi penyimpanan kunci hanya sekali selama masa pakai aplikasi.

Di .NET Framework 4.6.2 dan yang lebih baru, entri cache dikeluarkan setelah interval time-to-live yang dapat dikonfigurasi karena alasan keamanan. Nilai time-to-live default adalah 2 jam. Jika Anda memiliki persyaratan keamanan yang lebih ketat tentang berapa lama kunci enkripsi kolom dapat di-cache dalam teks biasa dalam aplikasi, Anda dapat mengubahnya menggunakan Properti SqlConnection.ColumnEncryptionKeyCacheTtl.

Mengaktifkan perlindungan ekstra untuk SQL Server yang disusupi

Secara default, Penyedia Data .NET Framework untuk SQL Server bergantung pada sistem database (SQL Server atau Azure SQL Database) untuk menyediakan metadata tentang kolom mana dalam database yang dienkripsi dan bagaimana. Metadata enkripsi memungkinkan Penyedia Data .NET Framework untuk SQL Server mengenkripsi parameter kueri dan mendekripsi hasil kueri tanpa input apa pun dari aplikasi, yang sangat mengurangi jumlah perubahan yang diperlukan dalam aplikasi. Namun, jika proses SQL Server disusupi dan penyerang merusak metadata yang dikirim SQL Server ke Penyedia Data .NET Framework untuk SQL Server, penyerang mungkin dapat mencuri informasi sensitif. Bagian ini menjelaskan API yang membantu memberikan tingkat perlindungan ekstra terhadap jenis serangan ini, dengan harga transparansi yang berkurang.

Memaksa enkripsi parameter

Sebelum Penyedia Data .NET Framework untuk SQL Server mengirim kueri berparameter ke SQL Server, ia meminta SQL Server (dengan memanggil sys.sp_describe_parameter_encryption) untuk menganalisis pernyataan kueri dan memberikan informasi tentang parameter mana dalam kueri yang harus dienkripsi. Instans SQL Server yang disusupi dapat menyesatkan Penyedia Data .NET Framework untuk SQL Server dengan mengirim metadata yang menunjukkan parameter tidak menargetkan kolom terenkripsi, meskipun kolom dienkripsi dalam database. Akibatnya, Penyedia Data .NET Framework untuk SQL Server tidak akan mengenkripsi nilai parameter, dan akan mengirimkannya sebagai teks biasa ke instans SQL Server yang disusupi.

Untuk mencegah serangan seperti itu , aplikasi dapat mengatur Properti SqlParameter.ForceColumnEncryption untuk parameter ke true. Ini akan menyebabkan Penyedia Data .NET Framework untuk SQL Server melemparkan pengecualian, jika metadata yang diterimanya dari server menunjukkan bahwa parameter tidak perlu dienkripsi.

Meskipun menggunakan Properti SqlParameter.ForceColumnEncryption membantu meningkatkan keamanan, ini juga mengurangi transparansi enkripsi ke aplikasi klien. Jika Anda memperbarui skema database untuk mengubah kumpulan kolom terenkripsi, Anda mungkin juga perlu membuat perubahan aplikasi.

Sampel kode berikut mengilustrasikan menggunakan Properti SqlParameter.ForceColumnEncryption untuk mencegah nomor jaminan sosial dikirim dalam teks biasa ke database.

SqlCommand cmd = _sqlconn.CreateCommand(); 

// Use parameterized queries to access Always Encrypted data. 
 
cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [SSN] = @SSN;"; 

SqlParameter paramSSN = cmd.CreateParameter(); 
paramSSN.ParameterName = @"@SSN"; 
paramSSN.DbType = DbType.AnsiStringFixedLength; 
paramSSN.Direction = ParameterDirection.Input; 
paramSSN.Value = ssn; 
paramSSN.Size = 11; 
paramSSN.ForceColumnEncryption = true; 
cmd.Parameters.Add(paramSSN); 

SqlDataReader reader = cmd.ExecuteReader();

Mengonfigurasi jalur Kunci Master Kolom tepercaya

Metadata enkripsi, SQL Server kembali untuk parameter kueri yang menargetkan kolom terenkripsi dan untuk hasil yang diambil dari kolom enkripsi, mencakup jalur kunci kunci master kolom yang mengidentifikasi penyimpanan kunci dan lokasi kunci di penyimpanan kunci. Jika instans SQL Server disusupi, instans tersebut dapat mengirim jalur kunci yang mengarahkan Penyedia Data .NET Framework untuk SQL Server ke lokasi yang dikendalikan oleh penyerang. Ini dapat menyebabkan bocornya kredensial penyimpanan kunci, dalam kasus penyimpanan kunci yang mengharuskan aplikasi untuk mengautentikasi.

Untuk mencegah serangan tersebut, aplikasi dapat menentukan daftar jalur kunci tepercaya untuk server tertentu menggunakan Properti SqlConnection.ColumnEncryptionTrustedMasterKeyPaths. Jika penyedia data kerangka kerja the.NET untuk SQL Server menerima jalur kunci di luar daftar jalur kunci tepercaya, itu akan melemparkan pengecualian.

Meskipun mengatur jalur kunci tepercaya meningkatkan keamanan aplikasi, Anda harus mengubah kode atau/dan konfigurasi aplikasi, setiap kali Anda memutar kunci master kolom (setiap kali jalur kunci master kolom berubah).

Contoh berikut menunjukkan cara mengonfigurasi jalur kunci master kolom tepercaya:

// Configure trusted key paths to protect against fake key paths sent by a compromised SQL Server instance 
// First, create a list of trusted key paths for your server 
List<string> trustedKeyPathList = new List<string>(); 
trustedKeyPathList.Add("CurrentUser/my/425CFBB9DDDD081BB0061534CE6AB06CB5283F5Ea"); 

// Register the trusted key path list for your server 

SqlConnection.ColumnEncryptionTrustedMasterKeyPaths.Add(serverName, trustedKeyPathList);

Menyalin data terenkripsi menggunakan SqlBulkCopy

Dengan SqlBulkCopy, 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. Catatan: jika salah satu kolom target 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 opsi AllowEncryptedValueModifications (lihat SqlBulkCopyOptions). Catatan: Berhati-hatilah saat menentukan AllowEncryptedValueModifications karena ini dapat menyebabkan kerusakan database karena Penyedia Data .NET Framework untuk SQL Server tidak memeriksa apakah data memang dienkripsi, atau jika dienkripsi dengan benar menggunakan jenis enkripsi, algoritma, dan kunci yang sama dengan kolom target.

Opsi AllowEncryptedValueModifications tersedia di .NET Framework 4.6.1 dan versi yang lebih baru.

Berikut adalah contoh yang menyalin data dari satu tabel ke tabel lainnya. Kolom SSN dan BirthDate diasumsikan untuk dienkripsi.

static public void CopyTablesUsingBulk(string sourceTable, string targetTable)
{
   string sourceConnectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true";
   string targetConnectionString = "Data Source= server64; Initial Catalog=Clinic; Integrated Security=true";
   using (SqlConnection connSource = new SqlConnection(sourceConnectionString))
   {
      connSource.Open();
      using (SqlCommand cmd = new SqlCommand(string.Format("SELECT [PatientID], [SSN], [FirstName], [LastName], [BirthDate] FROM {0}", sourceTable), connSource))
      {
         using (SqlDataReader reader = cmd.ExecuteReader())
         {
            SqlBulkCopy copy = new SqlBulkCopy(targetConnectionString, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.AllowEncryptedValueModifications);
            copy.EnableStreaming = true;
            copy.DestinationTableName = targetTable;
            copy.WriteToServer(reader);
         }
      }
}

referensi API Always Encrypted

Namespace:System.Data.SqlClient

Rakitan: System.Data (dalam System.Data.dll)

Nama Deskripsi Diperkenalkan dalam versi .NET
Kelas SqlColumnEncryptionCertificateStoreProvider Penyedia penyimpanan kunci untuk Penyimpanan Sertifikat Windows. 4.6
Kelas SqlColumnEncryptionCngProvider Penyedia penyimpanan kunci untuk Microsoft Cryptography API: Next Generation (CNG). 4.6.1
Kelas SqlColumnEncryptionCspProvider Penyedia penyimpanan kunci untuk Penyedia Layanan Kriptografi (CSP) berbasis Microsoft CAPI. 4.6.1
Kelas SqlColumnEncryptionKeyStoreProvider Kelas dasar penyedia penyimpanan kunci. 4.6
Enumerasi SqlCommandColumnEncryptionSetting Pengaturan untuk mengaktifkan enkripsi dan dekripsi untuk koneksi database. 4.6
Enumerasi SqlConnectionColumnEncryptionSetting Pengaturan untuk mengontrol perilaku Always Encrypted untuk kueri individual. 4.6
Properti SqlConnectionStringBuilder.ColumnEncryptionSetting Mendapatkan dan mengatur Always Encrypted dalam string koneksi. 4.6
Properti SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled Mengaktifkan dan menonaktifkan penembolokan metadata kueri enkripsi. 4.6.2
Properti SqlConnection.ColumnEncryptionKeyCacheTtl Mendapatkan dan mengatur time-to-live untuk entri dalam cache kunci enkripsi kolom. 4.6.2
Properti SqlConnection.ColumnEncryptionTrustedMasterKeyPaths Memungkinkan Anda mengatur daftar jalur kunci tepercaya untuk server database. Jika saat memproses kueri aplikasi, driver menerima jalur kunci yang tidak ada dalam daftar, kueri akan gagal. Properti ini memberikan perlindungan ekstra terhadap serangan keamanan yang melibatkan SQL Server yang disusupi yang menyediakan jalur kunci palsu, yang dapat menyebabkan kebocoran kredensial penyimpanan kunci. 4.6
Metode SqlConnection.RegisterColumnEncryptionKeyStoreProviders Memungkinkan Anda mendaftarkan penyedia penyimpanan kunci kustom. Ini adalah kamus yang memetakan nama penyedia penyimpanan kunci ke implementasi penyedia penyimpanan kunci. 4.6
Konstruktor SqlCommand (String, SqlConnection, SqlTransaction, SqlCommandColumnEncryptionSetting) Memungkinkan Anda mengontrol perilaku Always Encrypted untuk kueri individual. 4.6
Properti SqlParameter.ForceColumnEncryption Memberlakukan enkripsi parameter. Jika SQL Server memberi tahu driver bahwa parameter tidak perlu dienkripsi, kueri yang menggunakan parameter akan gagal. Properti ini memberikan perlindungan ekstra terhadap serangan keamanan yang melibatkan SQL Server yang disusupi yang memberikan metadata enkripsi yang salah kepada klien, yang dapat menyebabkan pengungkapan data. 4.6
Kata kunci string koneksi baru:Column Encryption Setting=enabled Mengaktifkan atau menonaktifkan fungsionalitas Always Encrypted untuk koneksi. 4.6

Baca juga