Aracılığıyla paylaş


SQL Server için .NET Framework Veri Sağlayıcısı ile Always Encrypted Kullanma

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen Örneği

Bu makale, Always Encrypted veya güvenli enklavlarla Always Encrypted kullanarak .NET Framework uygulamaları geliştirme ve SQL Server için .NET Framework Veri Sağlayıcısı (System.Data.SqlClient) hakkında bilgi sağlar.

Uyarı

YENI geliştirme için SQL Server (System.Data.SqlClient) için .NET Framework Veri Sağlayıcısı'nın kullanılması önerilmez. Daha fazla bilgi için bkz . System.Data.SqlClient.

Always Encrypted, istemci uygulamalarının hassas verileri şifrelemesine ve verileri veya şifreleme anahtarlarını SQL Server veya Azure SQL Veritabanı'na hiçbir zaman göstermemesini sağlar. SQL Server için .NET Framework Veri Sağlayıcısı gibi Always Encrypted özellikli bir sürücü, istemci uygulamasındaki hassas verileri saydam bir şekilde şifreleyerek ve şifresini çözerek bunu sağlar. Sürücü, hassas veritabanı sütunlarına hangi sorgu parametrelerinin karşılık olduğunu otomatik olarak belirler (Always Encrypted kullanılarak korunur) ve verileri SQL Server'a veya Azure SQL Veritabanı'na geçirmeden önce bu parametrelerin değerlerini şifreler. Benzer şekilde, sürücü sorgu sonuçlarında şifrelenmiş veritabanı sütunlarından alınan verilerin şifresini saydam bir şekilde çözer. Daha fazla bilgi için bkz . Always Encrypted kullanarak uygulama geliştirme ve Güvenli kuşatmalarla Always Encrypted kullanarak uygulama geliştirme.

Uyarı

SQL Server için .NET Framework Veri Sağlayıcısı (System.Data.SqlClient), kanıtlama olmadan VBS kuşatmalarının kullanılmasını desteklemez.

Önkoşullar

Uyarı

.NET Framework'ün belirli sürümlerinde Always Encrypted için destek düzeyi farklılık gösterir. Always Encrypted API başvuruları aşağıdaki bölümlerde listelenmiştir.

Uygulama sorguları için Always Encrypted'i etkinleştirme

Parametrelerin şifrelenmesini ve şifrelenmiş sütunları hedefleyen sorgu sonuçlarının şifresini çözmeyi etkinleştirmenin en kolay yolu, Sütun Şifreleme Ayarı bağlantı dizesi anahtar sözcüğü değerini etkin olarak ayarlamaktır.

Aşağıda Always Encrypted'i etkinleştiren bir bağlantı dizesi örneği verilmiştir:

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

Aşağıda, SqlConnectionStringBuilder.ColumnEncryptionSetting Özelliğini kullanan eşdeğer bir örnek verilmiştir.

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 tek tek sorgular için de etkinleştirilebilir. Aşağıdaki Always Encrypted'ın performans etkisini denetleme bölümüne bakın. Always Encrypted'ın etkinleştirilmesi şifreleme veya şifre çözme işlemlerinin başarılı olması için yeterli değildir. Ayrıca şunları da yapmanız gerekir:

  • Uygulama, veritabanındaki Always Encrypted anahtarları hakkındaki meta verilere erişmek için gereken HERHANGİ BİR SÜTUN ANAHTAR TANIMINI GÖRÜNTÜLE ve HERHANGİ BİR SÜTUN ŞİFRELEME ANAHTAR TANIMINI GÖRÜNTÜLE veritabanı izinlerine sahiptir. Ayrıntılar için Always Encrypted (Veritabanı Altyapısı) bölümündeki İzinler bölümüne bakın.
  • Uygulama, sorgulanan veritabanı sütunlarını şifreleyerek sütun şifreleme anahtarlarını koruyan sütun ana anahtarına erişebilir.

Güvenli kuşatmalarla Always Encrypted'ı etkinleştirme

.NET Framework 4.7.2 sürümünden başlayarak, sürücü güvenli kuşatmalarla Always Encrypted'ı destekler.

Kapanım hesaplamalarında ve kapanım kanıtlamasında istemci sürücüsü rolü hakkında genel bilgi için bkz. Güvenli kuşatmalarla Always Encrypted kullanarak uygulama geliştirme.

Uygulamanızı yapılandırmak için:

  1. Önceki bölümde açıklandığı gibi uygulama sorgularınız için Always Encrypted'ı etkinleştirin.

  2. Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders NuGet paketini uygulamanızla tümleştirin. NuGet, kanıt sunma protokolleri için istemci tarafı mantığını uygulayan ve güvenli bir enklav ile güvenli kanal oluşturan enklav sağlayıcılarının bir kitaplığıdır.

  3. Veritabanınız için yapılandırılmış bir kapanım türü ile bir kapanım sağlayıcısı arasındaki eşlemeyi tanımlamak için uygulama yapılandırmanızı güncelleştirin (örneğin, web.config veya app.config).

    1. SQL Server ve Konak Koruyucu Hizmeti (HGS) kullanıyorsanız, VBS kapanım türünü NuGet paketinden Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.HostGuardianServiceEnclaveProvider sınıfına eşlemeniz gerekir.
    2. Azure SQL Veritabanı ve Microsoft Azure Kanıtlama kullanıyorsanız, NuGet paketinden SGX kapanım türünü Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.AzureAttestationEnclaveProvider sınıfına eşlemeniz gerekir.

    Uygulama yapılandırmanızı düzenleme hakkında ayrıntılı yönergeler için bkz. Kılavuz: Güvenli kuşatmalarla Always Encrypted kullanarak .NET Framework uygulaması geliştirme.

  4. Enclave Attestation URL Veritabanı bağlantı dizenizdeki anahtar sözcüğü bir kanıtlama URL'si (kanıtlama hizmet uç noktası) olarak ayarlayın. Kanıtlama hizmeti yöneticinizden ortamınız için bir kanıtlama URL'si almanız gerekir.

    1. Eğer SQL Server ve Konak Koruyucu Hizmet (HGS) kullanıyorsanız, HGS kanıtlama URL'sini belirlemek ve paylaşmak için 'a ve'e bakın.
    2. Azure SQL Veritabanı ve Microsoft Azure Kanıtlama'yı kullanıyorsanız, kanıtlama politikanız için kanıtlama URL'sini belirleme başlığına bakın.

Adım adım öğretici için bkz: Güvenli alanlarla Always Encrypted ile .NET Framework uygulaması geliştirme öğreticisi

Şifrelenmiş sütunlardaki verileri alma ve değiştirme

Uygulama sorguları için Always Encrypted'ı etkinleştirdikten sonra, şifrelenmiş veritabanı sütunlarındaki verileri almak veya değiştirmek için standart ADO.NET API'lerini (bkz. ADO.NET Verileri Alma ve Değiştirme) veya System.Data.SqlClient Ad Alanı'nda tanımlanan SQL Server API'leri için .NET Framework Veri Sağlayıcısı'nı kullanabilirsiniz. Uygulamanızın gerekli veritabanı izinlerine sahip olduğunu ve sütun ana anahtarına erişebildiğini varsayarsak, SQL Server için .NET Framework Veri Sağlayıcısı şifrelenmiş sütunları hedefleyen tüm sorgu parametrelerini şifreler ve veritabanı şemasındaki sütunlar için ayarlanan SQL Server veri türlerine karşılık gelen .NET türlerinin düz metin değerlerini döndüren şifrelenmiş sütunlardan alınan verilerin şifresini çözer. Always Encrypted etkin değilse, şifrelenmiş sütunları hedefleyen parametrelere sahip sorgular başarısız olur. Sorguda şifrelenmiş sütunları hedefleyen parametre olmadığı sürece sorgular şifrelenmiş sütunlardan veri almaya devam edebilir. Ancak, SQL Server için .NET Framework Veri Sağlayıcısı şifrelenmiş sütunlardan alınan değerlerin şifresini çözmeyi denemez ve uygulama ikili şifrelenmiş verileri (bayt dizileri olarak) alır.

Aşağıdaki tabloda Always Encrypted'ın etkinleştirilip etkinleştirilmediğine bağlı olarak sorguların davranışı özetlenmiştir:

Sorgu özelliği Always Encrypted etkindir ve uygulama anahtarlara ve anahtar meta verilerine erişebilir Always Encrypted etkindir ve uygulama anahtarlara veya anahtar meta verilerine erişemez Always Encrypted devre dışı
Şifrelenmiş sütunları hedefleyen parametreleri olan sorgular. Parametre değerleri saydam olarak şifrelenir. Hata Hata
Şifrelenmiş sütunları hedefleyen parametreler olmadan şifrelenmiş sütunlardan veri alan sorgular. Şifrelenmiş sütunlardan elde edilen sonuçların şifresi saydam olarak çözülür. Uygulama, şifrelenmiş sütunlar için yapılandırılan SQL Server türlerine karşılık gelen .NET veri türlerinin düz metin değerlerini alır. Hata Şifrelenmiş sütunlardan elde edilen sonuçların şifresi çözülmez. Uygulama, şifrelenmiş değerleri bayt dizileri (bayt[]) olarak alır.

Aşağıdaki örneklerde şifrelenmiş sütunlardaki verilerin alınması ve değiştirilmesi gösterilmektedir. Örneklerde aşağıdaki şemaya sahip hedef tablo varsayılır. SSN ve BirthDate sütunları şifrelenir.

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

Veri ekleme örneği

Bu örnek, Patients tablosuna bir satır ekler. Aşağıdakilere dikkat edin:

  • Örnek kodda şifrelemeye özgü bir şey yoktur. SQL Server için .NET Framework Veri Sağlayıcısı, şifrelenmiş sütunları hedefleyen paramSSN ve paramBirthdate parametrelerini otomatik olarak algılar ve şifreler. Bu, şifrelemeyi uygulama için saydam hale getirir.
  • Şifrelenmiş sütunlar da dahil olmak üzere veritabanı sütunlarına eklenen değerler SqlParameter nesneleri olarak geçirilir. SqlParameter kullanımı, şifrelenmemiş sütunlara değer gönderirken isteğe bağlıdır (SQL eklemenin önlenmesine yardımcı olduğu için kesinlikle önerilir), şifrelenmiş sütunları hedefleyen değerler için gereklidir. SSN veya BirthDate sütunlarına eklenen değerler sorgu deyimine eklenmiş değişmez değerler olarak geçirildiyse, SQL Server için .NET Framework Veri Sağlayıcısı hedef şifrelenmiş sütunlardaki değerleri belirleyemediğinden sorgu başarısız olur ve bu nedenle değerleri şifrelemez. Sonuç olarak, sunucu bunları şifrelenmiş sütunlarla uyumsuz olarak reddeder.
  • SSN sütununu hedefleyen parametrenin veri türü, char/varchar SQL Server veri türüne eşlenen ANSI (Unicode olmayan) dizeye ayarlanır. Parametrenin türü nchar/nvarchar ile eşlenen bir Unicode dizesine (Dize) ayarlandıysa, Always Encrypted şifrelenmiş nchar/nvarchar değerlerinden şifrelenmiş karakter/varchar değerlerine dönüştürmeleri desteklemediğinden sorgu başarısız olur. Veri türü eşlemeleri hakkında bilgi için bkz. SQL Server Veri Türü Eşlemeleri.
  • BirthDate sütununa eklenen parametrenin veri türü, .NET türlerinin SqlParameter.DbType Özelliği kullanılırken uygulanan SQL Server veri türlerine örtük eşlemesi yerine SqlParameter.SqlDbType Özelliği kullanılarak açıkça hedef SQL Server veri türüne ayarlanır. Varsayılan olarak DateTime Yapısı, datetime SQL Server veri türüyle eşler. BirthDate sütununun veri türü tarih olduğundan ve Always Encrypted şifrelenmiş tarih saat değerlerinin şifrelenmiş tarih değerlerine dönüştürülmesi desteklemediğinden, varsayılan eşlemenin kullanılması hataya neden olur.
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();
   } 
}

Düz metin veri alma örneği

Aşağıdaki örnek, şifrelenmiş değerlere göre verileri filtrelemeyi ve şifrelenmiş sütunlardan düz metin verilerini almayı gösterir. Aşağıdakilere dikkat edin:

  • SQL Server için .NET Framework Veri Sağlayıcısı'nın veritabanına göndermeden önce saydam bir şekilde şifreleyebilmesi için, SSN sütununa filtre uygulamak için WHERE yan tümcesinde kullanılan değerin SqlParameter kullanılarak geçirilmesi gerekir.
  • SQL Server için .NET Framework Veri Sağlayıcısı SSN ve BirthDate sütunlarından alınan verilerin şifresini saydam bir şekilde çözeceği için, program tarafından yazdırılan tüm değerler düz metin biçiminde olacaktır.

Uyarı

Sorgular, belirleyici şifreleme kullanılarak şifrelenirse sütunlar üzerinde eşitlik karşılaştırmaları gerçekleştirebilir. Daha fazla bilgi için bkz. Deterministik veya Rastgele Şifreleme Seçme.

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());
 }

Şifrelenmiş verilerin alımı örneği

Always Encrypted etkinleştirilmemişse, sorgu şifrelenmiş sütunları hedefleyen parametreleri olmadığı sürece, sorgu şifrelenmiş sütunlardan verileri almaya devam edebilir.

Aşağıdaki örnek, şifrelenmiş sütunlardan ikili şifrelenmiş verilerin nasıl alınduğunu gösterir. Aşağıdakilere dikkat edin:

  • Bağlantı dizesinde Always Encrypted etkinleştirilmediğinden, sorgu bayt dizileri olarak SSN ve DoğumTarihi'nin şifrelenmiş değerlerini döndürür (program değerleri dizelere dönüştürür).
  • Always Encrypted devre dışı bırakılmış şifrelenmiş sütunlardan veri alan sorgunun parametreleri olabilir, ancak parametrelerin hiçbiri şifrelenmiş bir sütunu hedeflemez. Yukarıdaki sorgu LastName'e göre filtrelenir ve bu filtre veritabanında şifrelenmez. SSN veya BirthDate tarafından filtrelenen sorgu başarısız olur.
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]));
      }
   }
}

Şifrelenmiş sütunları sorgularken sık karşılaşılan sorunlardan kaçınma

Bu bölümde, .NET uygulamalarından şifrelenmiş sütunları sorgularken karşılaşılan yaygın hata kategorileri ve bunlardan kaçınmaya yönelik birkaç yönerge açıklanmaktadır.

Desteklenmeyen veri türü dönüştürme hataları

Always Encrypted, şifrelenmiş veri türleri için birkaç dönüştürmeyi destekler. Desteklenen tür dönüştürmelerinin ayrıntılı listesi için bkz . Always Encrypted . Veri türü dönüştürme hatalarını önlemek için aşağıdakileri yapın:

  • Şifrelenmiş sütunları hedefleyen parametre türlerini ayarlayın; böylece parametrenin SQL Server veri türü hedef sütunun türüyle tamamen aynıdır veya parametrenin SQL Server veri türünün sütunun hedef türüne dönüştürülmesi desteklenir. SqlParameter.SqlDbType Özelliğini kullanarak .NET veri türlerinin belirli SQL Server veri türlerine eşlemini zorunlu kılabilirsiniz.
  • Ondalık ve sayısal SQL Server veri türlerinin sütunlarını hedefleyen parametrelerin duyarlığı ve ölçeğinin, hedef sütun için yapılandırılan duyarlık ve ölçekle aynı olduğunu doğrulayın.
  • datetime2, datetimeoffset veya time SQL Server veri türlerinin sütunlarını hedefleyen parametrelerin duyarlık değerinin hedef sütun için duyarlıktan büyük olmadığını doğrulayın (hedef sütundaki değerleri değiştiren sorgularda).

Şifrelenmiş değerler yerine düz metin geçirme hataları

Şifrelenmiş sütunu hedefleyen tüm değerlerin uygulama içinde şifrelenmesi gerekir. Şifrelenmiş bir sütunda düz metin değerine göre ekleme/değiştirme veya filtreleme girişimi aşağıdakine benzer bir hatayla sonuçlanır:

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'

Bu tür hataları önlemek için şunlardan emin olun:

  • Always Encrypted, şifrelenmiş sütunları hedefleyen uygulama sorguları için etkinleştirilir (bağlantı dizesi için veya belirli bir sorgunun SqlCommand nesnesinde).
  • Şifrelenmiş sütunları hedefleyen verileri göndermek için SqlParameter kullanırsınız. Aşağıdaki örnekte, şifrelenmiş bir sütunda sabit bir değere (SSN) yanlış bir şekilde filtreleyen bir sorgu gösterilmektedir (sabit değer SqlParameter nesnesi içine geçirilmesi gerektiği halde).
using (SqlCommand cmd = connection.CreateCommand())
{
   cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN='795-73-9838'";
cmd.ExecuteNonQuery();
}

Sütun Anahtar depolarıyla çalışma

Bir parametre değerini şifrelemek veya sorgu sonuçlarındaki verilerin şifresini çözmek için, SQL Server için .NET Framework Veri Sağlayıcısının hedef sütun için yapılandırılmış bir sütun şifreleme anahtarı alması gerekir. Sütun şifreleme anahtarları, veritabanı meta verilerinde şifrelenmiş biçimde depolanır. Her sütun şifreleme anahtarının, sütun şifreleme anahtarını şifrelemek için kullanılan karşılık gelen bir sütun ana anahtarı vardır. Veritabanı meta verileri, sütun ana anahtarlarını depolamaz ve yalnızca belirli bir sütun ana anahtarını içeren bir anahtar deposu hakkındaki bilgileri ve anahtarın anahtar deposundaki konumunu içerir.

Bir sütun şifreleme anahtarının düz metin değerini almak için, SQL Server için .NET Framework Veri Sağlayıcısı önce hem sütun şifreleme anahtarı hem de ilgili sütun ana anahtarı hakkındaki meta verileri alır ve ardından meta verilerdeki bilgileri kullanarak anahtar deposuna başvurur, sütun ana anahtarını içerir ve şifrelenmiş sütun şifreleme anahtarının şifresini çözer. SQL Server için .NET Framework Veri Sağlayıcısı, sqlColumnEncryptionKeyStoreProvider Sınıfından türetilen bir sınıfın örneği olan bir sütun ana anahtar deposu sağlayıcısı kullanarak bir anahtar deposuyla iletişim kurar.

Sütun şifreleme anahtarı alma işlemi:

  1. Bir sorgu için Always Encrypted etkinleştirildiyse, SQL Server için .NET Framework Veri Sağlayıcısı, sorgunun parametreleri varsa şifrelenmiş sütunları hedefleyen parametreler için şifreleme meta verilerini almak üzere sys.sp_describe_parameter_encryption saydam olarak çağırır. Sorgu sonuçlarında yer alan şifrelenmiş veriler için SQL Server, şifreleme meta verilerini otomatik olarak ekler. Sütun ana anahtarıyla ilgili bilgiler şunları içerir:

    • Sütun ana anahtarını içeren bir anahtar depoyu kapsülleyen bir anahtar deposu sağlayıcısının adı.
    • Anahtar deposundaki sütun ana anahtarının konumunu belirten anahtar yolu.

    Sütun şifreleme anahtarıyla ilgili bilgiler şunları içerir:

    • Bir sütun şifreleme anahtarının şifrelenmiş değeri.
    • Sütun şifreleme anahtarını şifrelemek için kullanılan algoritmanın adı.
  2. SQL Server için .NET Framework Veri Sağlayıcısı, iç veri yapısında sağlayıcı nesnesini (SqlColumnEncryptionKeyStoreProvider Sınıfından türetilen bir sınıfın örneği) aramak için sütun ana anahtar deposu sağlayıcısının adını kullanır.

  3. Sütun şifreleme anahtarının şifresini çözmek için, SQL Server için .NET Framework Veri Sağlayıcısı SqlColumnEncryptionKeyStoreProvider.DecryptColumnEncryptionKey Yöntemini çağırır. Bu yöntem, sütun ana anahtar yolunu, sütun şifreleme anahtarının şifrelenmiş değerini ve şifrelenmiş sütun şifreleme anahtarını üretmek için kullanılan şifreleme algoritmasının adını geçirir.

Yerleşik sütun ana anahtar deposu sağlayıcılarını kullanma

SQL Server için .NET Framework Veri Sağlayıcısı, belirli sağlayıcı adlarıyla önceden kaydedilmiş aşağıdaki yerleşik sütun ana anahtar deposu sağlayıcılarıyla birlikte gelir (sağlayıcıyı aramak için kullanılır).

Class Description Sağlayıcı (arama) adı
SqlColumnEncryptionCertificateStoreProvider Sınıfı Windows Sertifika Deposu için bir sağlayıcı. MSSQL SERTİFİKA DEPOSU
SqlColumnEncryptionCngProvider Sınıfı

Not: Bu sağlayıcı .NET Framework 4.6.1 ve sonraki sürümlerde kullanılabilir.
Microsoft Şifreleme API'sini destekleyen bir anahtar deposu sağlayıcısı : Yeni Nesil (CNG) API'si. Genellikle, bu tür bir depo, dijital anahtarları koruyan ve yöneten ve şifreleme işleme sağlayan fiziksel bir cihaz olan bir donanım güvenlik modülüdür. MSSQL_CNG_STORE
SqlColumnEncryptionCspProvider Sınıfı

Not: Bu sağlayıcı .NET Framework 4.6.1 veya sonraki sürümlerde kullanılabilir.
Microsoft Şifreleme API'sini (CAPI) destekleyen bir anahtar deposu sağlayıcısı. Genellikle, bu tür bir depo, dijital anahtarları koruyan ve yöneten ve şifreleme işleme sağlayan fiziksel bir cihaz olan bir donanım güvenlik modülüdür. MSSQL_CSP_PROVIDER

Bu sağlayıcıları kullanmak için uygulama kodunda herhangi bir değişiklik yapmanız gerekmez, ancak aşağıdakileri not edin:

  • Siz (veya DBA'nız) sütun ana anahtar meta verilerinde yapılandırılan sağlayıcı adının doğru olduğundan ve sütun ana anahtar yolunun belirli bir sağlayıcı için geçerli olan anahtar yolu biçimiyle uyumlu olduğundan emin olmanız gerekir. CREATE COLUMN MASTER KEY (Transact-SQL) deyimini verirken geçerli sağlayıcı adlarını ve anahtar yollarını otomatik olarak oluşturan SQL Server Management Studio gibi araçları kullanarak anahtarları yapılandırmanız önerilir. Daha fazla bilgi için bkz . SQL Server Management Studio kullanarak Always Encrypted'ı yapılandırma ve PowerShell kullanarak Always Encrypted'ı yapılandırma.
  • Uygulamanızın anahtar deposundaki anahtara erişebildiğinden emin olun. Uygulamanıza anahtara ve/veya anahtar deposuna erişim izni vermeyi veya anahtar deposuna özgü diğer yapılandırma adımlarını gerçekleştirmeyi içerebilir. Örneğin, CNG veya CAPI uygulayan bir anahtar deposuna erişmek için (örneğin, bir donanım güvenlik modülü), mağazanız için CNG veya CAPI uygulayan bir kitaplığın uygulama makinenizde yüklü olduğundan emin olmanız gerekir. Ayrıntılar için bkz. Always Encrypted için sütun ana anahtarları oluşturma ve depolama.

Azure Key Vault sağlayıcısını kullanma

Azure Key Vault, Always Encrypted için sütun ana anahtarlarını depolamak ve yönetmek için kullanışlı bir seçenektir (özellikle de uygulamalarınız Azure'da barındırılıyorsa). SQL Server için .NET Framework Veri Sağlayıcısı, Azure Key Vault için yerleşik bir sütun ana anahtar deposu sağlayıcısı içermez, ancak uygulamanızla kolayca tümleştirebileceğiniz bir NuGet paketi olarak kullanılabilir. Ayrıntılar için bkz:

Özel sütun ana anahtar deposu sağlayıcısı uygulama

Sütun ana anahtarlarını var olan bir sağlayıcı tarafından desteklenmeyen bir anahtar deposunda depolamak istiyorsanız, SqlColumnEncryptionCngProvider Sınıfını genişleterek ve SqlConnection.RegisterColumnEncryptionKeyStoreProviders yöntemini kullanarak sağlayıcıyı kaydederek özel bir sağlayıcı uygulayabilirsiniz.

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); 
       // ...
        }

    }

Programlı anahtar sağlama için sütun ana anahtar deposu sağlayıcılarını kullanma

Şifrelenmiş sütunlara erişirken, SQL Server için .NET Framework Veri Sağlayıcısı sütun şifreleme anahtarlarının şifresini çözmek için doğru sütun ana anahtar deposu sağlayıcısını saydam bir şekilde bulur ve çağırır. Normal uygulama kodunuz genellikle sütun ana anahtar deposu sağlayıcılarını doğrudan çağırmaz. Bununla birlikte, Always Encrypted anahtarlarını program aracılığıyla sağlamak ve yönetmek için bir sağlayıcının örneğini oluşturabilir ve çağırabilirsiniz: şifrelenmiş bir sütun şifreleme anahtarı oluşturmak ve bir sütun şifreleme anahtarının şifresini çözmek için (örneğin, sütun ana anahtarı döndürme). Daha fazla bilgi için bkz. Always Encrypted için anahtar yönetimine genel bakış. Kendi anahtar yönetimi araçlarınızı uygulamak yalnızca özel anahtar deposu sağlayıcısı kullanıyorsanız gerekli olabilir. Yerleşik sağlayıcıların bulunduğu anahtar depolarında veya Azure Key Vault'ta depolanan anahtarları kullanırken, anahtarları yönetmek ve sağlamak için SQL Server Management Studio veya PowerShell gibi mevcut araçları kullanabilirsiniz. Aşağıdaki örnekte, bir sütun şifreleme anahtarı oluşturma ve anahtarı bir sertifikayla şifrelemek için SqlColumnEncryptionCertificateStoreProvider Sınıfını kullanma gösterilmektedir.

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

static byte[]  GetEncryptedColumnEncryptionKey()
{
    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); 
}

Always Encrypted'ın performans etkisini denetleme

Always Encrypted bir istemci tarafı şifreleme teknolojisi olduğundan, performans ek yüklerinin çoğu veritabanında değil istemci tarafında gözlemlenir. Şifreleme ve şifre çözme işlemlerinin maliyeti dışında, istemci tarafındaki diğer performans ek yükleri kaynakları şunlardır:

  • Sorgu parametrelerinin meta verilerini almak için veritabanına fazladan gidiş dönüşler.
  • Bir sütun ana anahtarına erişmek için bir sütun ana anahtar deposuna çağrılar.

Bu bölümde SQL Server için .NET Framework Sağlayıcısı'ndaki yerleşik performans iyileştirmeleri ve yukarıdaki iki faktörün performans üzerindeki etkisini nasıl denetleyebileceğiniz açıklanmaktadır.

Sorgu parametreleri için meta verileri almak için gidiş dönüşleri denetleme

Always Encrypted bir bağlantı için etkinleştirildiyse, SQL Server için .NET Framework Veri Sağlayıcısı varsayılan olarak her parametreli sorgu için sys.sp_describe_parameter_encryption çağırır ve sorgu deyimini (parametre değerleri olmadan) SQL Server'a geçirir. sys.sp_describe_parameter_encryption , herhangi bir parametrenin şifrelenmesi gerekip gerekmediğini öğrenmek için sorgu deyimini analiz eder ve varsa her biri için SQL Server için .NET Framework Veri Sağlayıcısı'nın parametre değerlerini şifrelemesine olanak sağlayacak şifrelemeyle ilgili bilgileri döndürür. Yukarıdaki davranış, istemci uygulaması için yüksek düzeyde saydamlık sağlar. Şifrelenmiş sütunları hedefleyen değerler SqlParameter nesnelerinde SQL Server için .NET Framework Veri Sağlayıcısı'na geçirildiği sürece uygulamanın (ve uygulama geliştiricisinin) hangi sorguların şifrelenmiş sütunlara eriştiğini bilmesi gerekmez.

Sorgu meta verileri önbelleğe alma

.NET Framework 4.6.2 ve sonraki sürümlerinde, SQL Server için .NET Framework Veri Sağlayıcısı her sorgu deyimi için sys.sp_describe_parameter_encryption sonuçlarını önbelleğe alır. Bu nedenle, aynı sorgu deyimi birden çok kez yürütülürse, sürücü sys.sp_describe_parameter_encryption yalnızca bir kez çağırır. Sorgu deyimleri için şifreleme meta verileri önbelleğe alma, veritabanından meta verileri getirmenin performans maliyetini önemli ölçüde azaltır. Önbelleğe alma varsayılan olarak etkindir. SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled Özelliğini false olarak ayarlayarak parametre meta verilerini önbelleğe almayı devre dışı bırakabilirsiniz, ancak aşağıda açıklanan gibi nadir durumlar dışında bunu yapmanız önerilmez:

İki farklı şeması olan bir veritabanını düşünün: s1 ve s2. Her şema aynı ada sahip bir tablo içerir: t. s1.t ve s2.t tablolarının tanımları, şifreleme ile ilgili özellikler dışında, aynıdır: c tablosundaki s1.t adlı sütun şifrelenmezken, bu sütun s2.t tablosunda şifrelenmiştir. Veritabanının iki kullanıcısı vardır: u1 ve u2. Kullanıcıların varsayılan şemasıdır u1s1. için u2 varsayılan şemadır s2. .NET uygulaması, veritabanına iki bağlantı açar; bir bağlantıda u1 kullanıcısının kimliğine, diğer bağlantıda ise u2 kullanıcısının kimliğine bürünür. Uygulama, kullanıcı c için bağlantı üzerinden sütunu hedefleyen u1 bir parametre içeren bir sorgu gönderir (sorgu şemayı belirtmediğinden, varsayılan kullanıcı şeması varsayılır). Ardından uygulama, kullanıcı için bağlantı üzerinden aynı sorguyu u2 gönderir. Sorgu meta verilerini önbelleğe alma etkinleştirilirse, ilk sorgudan sonra önbellek sütunu gösteren c meta verilerle doldurulur, sorgu parametresi hedefleri şifrelenmez. İkinci sorgu aynı sorgu deyimine sahip olduğundan, önbellekte depolanan bilgiler kullanılır. Sonuç olarak, sürücü parametreyi şifrelemeden (hedef sütun s2.t.c şifrelendiğinden yanlıştır) sorguyu gönderir ve parametrenin düz metin değerini sunucuya sızdıracaktır. Sunucu bu uyumsuzluğu algılar ve sürücüyü önbelleği yenilemeye zorlar, bu nedenle uygulama sorguyu doğru şifrelenmiş parametre değeriyle saydam bir şekilde yeniden gönderir. Böyle bir durumda, hassas değerlerin sunucuya sızmasını önlemek için önbelleğe alma devre dışı bırakılmalıdır.

Always Encrypted'i sorgu düzeyinde ayarlama

Parametreli sorgular için şifreleme meta verilerini alma performansının etkisini denetlemek için, bağlantı için ayarlamak yerine tek tek sorgular için Always Encrypted'ı etkinleştirebilirsiniz. Bu şekilde, sys.sp_describe_parameter_encryption yalnızca şifrelenmiş sütunları hedefleyen parametreleri olduğunu bildiğiniz sorgular için çağrıldığından emin olabilirsiniz. Bununla birlikte, bunu yaparak şifreleme saydamlığını azalttığınızı unutmayın: Veritabanı sütunlarınızın şifreleme özelliklerini değiştirirseniz, uygulamanızın kodunu şema değişiklikleriyle uyumlu hale getirmek için değiştirmeniz gerekebilir.

Uyarı

Always Encrypted ayarının sorgu düzeyinde ayarlanması, parametre şifrelemesi meta verilerini önbelleğe alan .NET 4.6.2 ve sonraki sürümlerde sınırlı performans avantajlarına sahiptir.

Bireysel sorguların Always Encrypted davranışını denetlemek için, SqlCommand oluşturucusunu ve SqlCommandColumnEncryptionSetting oluşturucusunu kullanmanız gerekir. Bazı yararlı yönergeler şunlardır:

  • Çoğu sorgu bir istemci uygulaması bir veritabanı bağlantısı üzerinden gönderirse şifrelenmiş sütunlara erişin:
    • Sütun Şifreleme Ayarı bağlantı dizesi anahtar sözcüğünü Etkin olarak ayarlayın.
    • Şifrelenmiş sütunlara erişmeyen tek tek sorgular için SqlCommandColumnEncryptionSetting.Disabled değerini ayarlayın. Bu, hem sys.sp_describe_parameter_encryption çağrısını hem de sonuç kümesindeki değerlerin şifre çözme girişimini devre dışı bırakır.
    • Şifreleme gerektiren parametreleri olmayan ancak şifrelenmiş sütunlardan veri alan tek tek sorgular için SqlCommandColumnEncryptionSetting.ResultSet değerini ayarlayın. Bu, sys.sp_describe_parameter_encryption ve parametre şifrelemesini çağırmayı devre dışı bırakır. Sorgu, şifreleme sütunlarından sonuçların şifresini çözebilir.
  • İstemci uygulamasının veritabanı bağlantısı üzerinden gönderdiği sorguların çoğu şifrelenmiş sütunlara erişmiyorsa:
    • Sütun Şifreleme Ayarı bağlantı dizesi anahtarını Devre Dışı olarak ayarlayın.
    • Şifrelenmesini gerektiren parametreleri olan tek tek sorgular için SqlCommandColumnEncryptionSetting.Enabled değerini ayarlayın. Bu, hem sys.sp_describe_parameter_encryption prosedürünü çağırmayı hem de şifrelenmiş sütunlardan alınan sorgu sonuçlarının şifresini çözmeyi etkinleştirir.
    • Şifreleme gerektiren parametreleri olmayan ancak şifrelenmiş sütunlardan veri alan sorgular için SqlCommandColumnEncryptionSetting.ResultSet değerini ayarlayın. Bu, sys.sp_describe_parameter_encryption ve parametre şifrelemesini çağırmayı devre dışı bırakır. Sorgu, şifreleme sütunlarından sonuçların şifresini çözebilir.

Aşağıdaki örnekte, veritabanı bağlantısı için Always Encrypted devre dışı bırakılmıştır. Uygulamanın oluşturduğu sorgu, şifrelenmemiş LastName sütununu hedefleyen bir parametre içerir. Sorgu, her ikisi de şifrelenmiş SSN ve BirthDate sütunlarından veri alır. Böyle bir durumda, şifreleme meta verilerini almak için sys.sp_describe_parameter_encryption çağırmak gerekli değildir. Ancak, uygulamanın şifrelenmiş iki sütundan düz metin değerleri alabilmesi için sorgu sonuçlarının şifresinin çözülmesinin etkinleştirilmesi gerekir. Emin olmak için SqlCommandColumnEncryptionSetting.ResultSet ayarı kullanılır.

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());
                  }
               }
            }
  } 
}

Sütun şifreleme anahtarı önbelleğe alma

Sütun şifreleme anahtarlarının şifresini çözmek için bir sütun ana anahtar deposuna yapılan çağrı sayısını azaltmak için, SQL Server için .NET Framework Veri Sağlayıcısı düz metin sütun şifreleme anahtarlarını bellekte önbelleğe alır. Veritabanı meta verilerinden şifrelenmiş sütun şifreleme anahtarı değerini aldıktan sonra, sürücü önce şifrelenmiş anahtar değerine karşılık gelen düz metin sütun şifreleme anahtarını bulmaya çalışır. Sürücü, yalnızca önbellekte şifrelenmiş sütun şifreleme anahtarı değerini bulamazsa, sütun ana anahtarını içeren anahtar depoyu çağırır.

Uyarı

.NET Framework 4.6 ve 4.6.1'de önbellekteki sütun şifreleme anahtarı girişleri asla silinmez. Başka bir deyişle, belirli bir şifrelenmiş sütun şifreleme anahtarı için sürücü, uygulamanın kullanım ömrü boyunca anahtar deposuyla yalnızca bir kez iletişim kurar.

.NET Framework 4.6.2 ve sonraki sürümlerinde önbellek girdileri, güvenlik nedeniyle yapılandırılabilir bir yaşam süresi aralığından sonra çıkarılır. Varsayılan yaşam süresi değeri 2 saattir. Sütun şifreleme anahtarlarının uygulamada düz metin olarak ne kadar süreyle önbelleğe alınabileceği konusunda daha katı güvenlik gereksinimleriniz varsa, SqlConnection.ColumnEncryptionKeyCacheTtl Özelliğini kullanarak bunu değiştirebilirsiniz.

Güvenliği aşılmış bir SQL Server için ek korumayı etkinleştirme

Varsayılan olarak, SQL Server için .NET Framework Veri Sağlayıcısı veritabanındaki hangi sütunların şifrelendiği ve nasıl şifrelendiği hakkında meta veriler sağlamak için veritabanı sistemine (SQL Server veya Azure SQL Veritabanı) dayanır. Şifreleme meta verileri, SQL Server için .NET Framework Veri Sağlayıcısı'nın sorgu parametrelerini şifrelemesine ve uygulamadan herhangi bir giriş yapmadan sorgu sonuçlarının şifresini çözmesine olanak tanır ve bu da uygulamada gereken değişiklik sayısını büyük ölçüde azaltır. Ancak, SQL Server işleminin gizliliği ihlal edilirse ve bir saldırgan SQL Server'ın SQL Server için .NET Framework Veri Sağlayıcısı'na gönderdiği meta verilerle oynanırsa, saldırgan hassas bilgileri çalabilir. Bu bölümde, daha düşük saydamlık karşılığında bu tür saldırılara karşı ek bir koruma düzeyi sağlamaya yardımcı olan API'ler açıklanmaktadır.

Parametre şifrelemesini mecbur kılma

SQL Server için .NET Framework Veri Sağlayıcısı SQL Server'a parametreli bir sorgu göndermeden önce, SQL Server'dan ( sys.sp_describe_parameter_encryption çağırarak) sorgu deyimini çözümlemesini ve sorgudaki hangi parametrelerin şifrelenmesi gerektiği hakkında bilgi vermesini ister. Güvenliği aşılmış bir SQL Server örneği, veritabanında şifrelenmiş olsa bile parametrenin şifrelenmiş bir sütunu hedeflemediğini belirten meta verileri göndererek SQL Server için .NET Framework Veri Sağlayıcısını yanıltabilir. Sonuç olarak, SQL Server için .NET Framework Veri Sağlayıcısı parametre değerini şifrelemez ve güvenliği aşılmış SQL Server örneğine düz metin olarak gönderir.

Böyle bir saldırıyı önlemek için bir uygulama, parametresi için SqlParameter.ForceColumnEncryption Özelliğini true olarak ayarlayabilir. Bu, sunucudan aldığı meta veriler parametrenin şifrelenmesinin gerekmediğini gösteriyorsa SQL Server için .NET Framework Veri Sağlayıcısı'nın bir özel durum oluşturmasına neden olur.

SqlParameter.ForceColumnEncryption Özelliğinin kullanılması güvenliği artırmaya yardımcı olsa da, istemci uygulaması için şifreleme saydamlığını da azaltır. Şifrelenmiş sütun kümesini değiştirmek için veritabanı şemasını güncelleştirirseniz, uygulama değişiklikleri de yapmanız gerekebilir.

Aşağıdaki kod örneği, sosyal güvenlik numaralarının veritabanına düz metin olarak gönderilmesini önlemek için SqlParameter.ForceColumnEncryption Özelliğinin kullanılmasını gösterir.

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();

Güvenilen Sütun Ana Anahtarı yollarını yapılandırma

SQL Server, şifreleme meta verilerini, şifrelenmiş sütunları hedefleyen sorgu parametreleri ve şifreleme sütunlarından alınan sonuçlar için döndürür. Bu veriler, anahtar deposunu ve anahtarın bu depodaki konumunu tanımlayan sütun ana anahtarının anahtar yolunu içerir. SQL Server örneğinin güvenliği aşılırsa, SQL Server için .NET Framework Veri Sağlayıcısı'nı bir saldırgan tarafından denetlenen konuma yönlendiren anahtar yolunu gönderebilir. Bu, uygulamanın kimlik doğrulamasını gerektiren anahtar deposu söz konusu olduğunda anahtar deposu kimlik bilgilerinin sızmasına neden olabilir.

Bu tür saldırıları önlemek için uygulama, SqlConnection.ColumnEncryptionTrustedMasterKeyPaths Özelliğini kullanarak belirli bir sunucu için güvenilen anahtar yollarının listesini belirtebilir. SQL Server için the.NET Framework Veri Sağlayıcısı güvenilen anahtar yolu listesinin dışında bir anahtar yolu alırsa, bir özel durum oluşturur.

Güvenilen anahtar yollarını ayarlamak uygulamanızın güvenliğini artırsa da, sütun ana anahtarınızı her döndürdüğünüzde (sütun ana anahtarı yolu değiştiğinde) kodu veya/ve uygulamanın yapılandırmasını değiştirmeniz gerekir.

Aşağıdaki örnekte, güvenilen sütun ana anahtar yollarının nasıl yapılandırılır gösterilmektedir:

// 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);

SqlBulkCopy kullanarak şifrelenmiş verileri kopyalama

SqlBulkCopy ile verilerin şifresini çözmeden zaten şifrelenmiş ve bir tabloda depolanan verileri başka bir tabloya kopyalayabilirsiniz. Bunu yapmak için:

  • Hedef tablonun şifreleme yapılandırmasının kaynak tablonun yapılandırmasıyla aynı olduğundan emin olun. Özellikle, her iki tabloda da aynı sütunlar şifrelenmeli ve sütunlar aynı şifreleme türleri ve aynı şifreleme anahtarları kullanılarak şifrelenmelidir. Not: Hedef sütunlardan herhangi biri karşılık gelen kaynak sütunundan farklı şekilde şifrelenirse, kopyalama işleminden sonra hedef tablodaki verilerin şifresini çözemezsiniz. Veriler bozulur.
  • Always Encrypted etkin olmadan kaynak tabloya ve hedef tabloya her iki veritabanı bağlantısını da yapılandırın.
  • AllowEncryptedValueModifications seçeneğini ayarlayın (bkz . SqlBulkCopyOptions). Not: AllowEncryptedValueModifications değerini belirtirken dikkatli olun çünkü SQL Server için .NET Framework Veri Sağlayıcısı verilerin gerçekten şifrelenip şifrelenmediğini veya hedef sütunla aynı şifreleme türü, algoritma ve anahtar kullanılarak doğru şekilde şifrelenip şifrelenmediğini denetlemediğinden veritabanının bozulmasına neden olabilir.

AllowEncryptedValueModifications seçeneği .NET Framework 4.6.1 ve sonraki sürümlerde kullanılabilir.

Burada verileri bir tablodan diğerine kopyalayan bir örnek verilmiştir. SSN ve BirthDate sütunlarının şifrelendiği varsayılır.

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);
         }
      }
}

Always Encrypted API referansı

Ad Alanı:System.Data.SqlClient

Derleme: System.Data (System.Data.dll içinde)

İsim Description .NET sürümünde kullanıma sunulmuştur
SqlColumnEncryptionCertificateStoreProvider Sınıfı Windows Sertifika Deposu için bir anahtar deposu sağlayıcısı. 4.6
SqlColumnEncryptionCngProvider Sınıfı Microsoft Şifreleme API'si için bir anahtar deposu sağlayıcısı: Yeni Nesil (CNG). 4.6.1
SqlColumnEncryptionCspProvider Sınıfı Microsoft CAPI tabanlı Şifreleme Hizmeti Sağlayıcıları (CSP) için bir anahtar deposu sağlayıcısı. 4.6.1
SqlColumnEncryptionKeyStoreProvider Sınıfı Anahtar deposu sağlayıcılarının temel sınıfı. 4.6
SqlCommandColumnEncryptionSetting Sabit Listesi Veritabanı bağlantısı için şifrelemeyi ve şifre çözmeyi etkinleştirme ayarları. 4.6
SqlConnectionColumnEncryptionSetting Sabit Listesi Tek tek sorgular için Always Encrypted davranışını denetleme ayarları. 4.6
SqlConnectionStringBuilder.ColumnEncryptionSetting Özelliği Bağlantı dizesinde Always Encrypted'ı alır ve ayarlar. 4.6
SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled Özelliği Şifreleme sorgusu meta verilerini önbelleğe almayı etkinleştirir ve devre dışı bırakır. 4.6.2
SqlConnection.ColumnEncryptionKeyCacheTtl Özelliği Sütun şifreleme anahtarı önbelleğindeki girdilerin yaşam süresini alır ve ayarlar. 4.6.2
SqlConnection.ColumnEncryptionTrustedMasterKeyPaths Özelliği Veritabanı sunucusu için güvenilen anahtar yollarının listesini ayarlamanıza olanak tanır. Bir uygulama sorgusu işlenirken sürücü listede olmayan bir anahtar yolu alırsa, sorgu başarısız olur. Bu özellik, güvenliği aşılmış bir SQL Server'ın sahte anahtar yolları sağlamasını içeren ve anahtar deposu kimlik bilgilerinin sızmasına neden olabilecek güvenlik saldırılarına karşı ek koruma sağlar. 4.6
SqlConnection.RegisterColumnEncryptionKeyStoreProviders Yöntemi Özel anahtar deposu sağlayıcılarını kaydetmenizi sağlar. Anahtar deposu sağlayıcı adlarını anahtar deposu sağlayıcı uygulamalarıyla eşleyen bir sözlüktür. 4.6
SqlCommand Oluşturucu (String, SqlConnection, SqlTransaction, SqlCommandColumnEncryptionSetting) Tek tek sorgular için Always Encrypted davranışını denetlemenizi sağlar. 4.6
SqlParameter.ForceColumnEncryption Özelliği Bir parametrenin şifrelenmesini zorlar. SQL Server sürücüye parametrenin şifrelenmesinin gerekmediğini bildirirse, parametresini kullanan sorgu başarısız olur. Bu özellik, istemciye yanlış şifreleme meta verileri sağlayan güvenliği aşılmış bir SQL Server içeren güvenlik saldırılarına karşı ek koruma sağlar ve bu da verilerin açığa çıkmasına neden olabilir. 4.6
Yeni bağlantı dizesi anahtar sözcüğü: Column Encryption Setting=enabled Bağlantı için Always Encrypted işlevselliğini etkinleştirir veya devre dışı bırakır. 4.6

Ayrıca bakınız