Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
JDBC sürücüsünü indirin
Bu sayfada, SQL Server için Microsoft JDBC Driver 6.0 (veya üzeri) ile Always Encrypted kullanmak üzere Java uygulamaları geliştirme hakkında bilgi sağlanır.
Always Encrypted istemcilerin hassas verileri şifrelemesine ve verileri veya şifreleme anahtarlarını SQL Server veya Azure SQL Veritabanı'na asla göstermemesini sağlar. SQL Server için Microsoft JDBC Driver 6.0 (veya üzeri) gibi Always Encrypted özellikli bir sürücü, istemci uygulamasında hassas verileri saydam bir şekilde şifreleyerek ve şifresini çözerek bu davranışa ulaşır. Sürücü, hangi sorgu parametrelerinin Always Encrypted veritabanı sütunlarına karşılık olduğunu belirler ve bu parametreleri veritabanına göndermeden ö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, Always Encrypted (Veritabanı Altyapısı) ve JDBC sürücüsü için Always Encrypted API referansıbölümlerine bakın.
Önkoşullar
- Geliştirme makinenizde SQL Server için Microsoft JDBC Driver 6.0 (veya üzeri) yüklü olduğundan emin olun.
- Java Şifreleme Uzantısı (JCE) Sınırsız Güçlü Yargı Alanı İlkesi Dosyalarını indirin ve yükleyin. Yükleme yönergeleri ve olası dışarı aktarma veya içeri aktarma sorunlarıyla ilgili ayrıntılar için zip dosyasındaki Benioku dosyasını okuduğunuzdan emin olun.
- mssql-jdbc-X.X.X.jre7.jar veya sqljdbc41.jar için, ilke dosyaları Java Şifreleme Uzantısı (JCE) Sınırsız Güç Yetki Alanı İlke Dosyaları 7 İndirme Bağlantıları
- mssql-jdbc-X.X.X.jre8.jar veya sqljdbc42.jar için, ilke dosyaları Java Şifreleme Uzantısı (JCE) Sınırsız Güç Yargı Yetkisi İlke Dosyaları 8 İndir
- Herhangi bir JRE sürüm 9 veya üzeri (örneğin, mssql-jdbc-X.X.X.jre9.jar) için hiçbir ilke dosyasının indirilmesi gerekmez. Java 9 ve üzeri işletim sistemindeki yargı alanı ilkesi, varsayılan olarak sınırsız güçlü şifrelemeye sahiptir.
Sütun ana anahtar depolarıyla çalışma
Sql Server, şifrelenmiş sütunlar için verileri şifrelemek veya şifresini çözmek için sütun şifreleme anahtarlarını korur. 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ı içermez. Bu anahtarlar yalnızca istemci tarafından tutulur. Ancak veritabanı meta verileri, sütun ana anahtarlarının istemciye göre nerede depolandığı hakkında bilgi içerir. Örneğin, veritabanı meta verileri sütun ana anahtarını barındıran anahtar deposunun Windows Sertifika Deposu olduğunu ve şifrelemek ve şifresini çözmek için kullanılan belirli sertifikanın Windows Sertifika Deposu içindeki belirli bir yolda bulunduğunu söyleyebilir.
İstemcinin Windows Sertifika Deposu'nda bu sertifikaya erişimi varsa, sertifikayı alabilir. Daha sonra sertifika, sütun şifreleme anahtarının şifresini çözmek için kullanılabilir. Daha sonra bu şifreleme anahtarı, bu sütun şifreleme anahtarını kullanan şifrelenmiş sütunlar için verilerin şifresini çözmek veya şifrelemek için kullanılabilir.
Microsoft JDBC Sürücüsü, SQL Server için SQLServerColumnEncryptionKeyStoreProvider'dan türetilmiş bir sınıfın örneği olan bir sütun anahtar deposu sağlayıcısı kullanan bir anahtar deposuyla iletişim kurar.
Yerleşik sütun ana anahtar deposu sağlayıcılarını kullanma
SQL Server için Microsoft JDBC Sürücüsü aşağıdaki yerleşik sütun ana anahtar deposu sağlayıcılarıyla birlikte gelir. Bu sağlayıcılardan bazıları belirli sağlayıcı adlarıyla önceden kaydedilir (sağlayıcıyı aramak için kullanılır) ve bazıları ek kimlik bilgileri veya açık kayıt gerektirir.
| Sınıf | Açıklama | Sağlayıcı (arama) adı | Önceden kayıtlı mı? | Peron |
|---|---|---|---|---|
SQLServerColumnEncryptionAzureKeyVaultProvider |
Azure Key Vault için anahtar deposu sağlayıcısı. | AZURE_KEY_VAULT | JDBC sürücüsü sürüm 7.4.1'in öncesinde yok, ancak JDBC sürücüsü sürüm 7.4.1'e göre evet . | Windows, Linux, macOS |
SQLServerColumnEncryptionCertificateStoreProvider |
Windows Sertifika Deposu için bir sağlayıcı. | MSSQL_SERTİFİKA_DEPOSU | Evet | Windows |
SQLServerColumnEncryptionJavaKeyStoreProvider |
Java anahtar deposu için bir sağlayıcı. | MSSQL_JAVA_KEYSTORE | Evet | Windows, Linux, macOS |
Önceden kaydedilen anahtar deposu sağlayıcıları için, bu sağlayıcıları kullanmak için herhangi bir uygulama kodu değişikliğine ihtiyacınız yoktur, ancak aşağıdaki öğeleri not edin:
- 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çimini izlediğinden emin olmanız gerekir. Anahtarları SQL Server Management Studio gibi araçlarla yapılandırmanız önerilir. Bu araçlar,
CREATE COLUMN MASTER KEY(Transact-SQL) deyimini vermek için geçerli sağlayıcı adlarını ve anahtar yollarını otomatik olarak oluşturur. - Uygulamanızın anahtar deposundaki anahtara erişebildiğinden emin olun. Bu görev, uygulamanıza anahtara ve/veya anahtar deposuna erişim verilmesini içerebilir. Anahtar deposuna bağlı olarak, bu anahtar deposuna özgü diğer yapılandırma adımlarını içerebilir. Örneğin,
SQLServerColumnEncryptionJavaKeyStoreProviderkullanmak için bağlantı özelliklerinde anahtar deposunun konumunu ve parolasını sağlamanız gerekir.
Bu anahtar deposu sağlayıcılarının tümü, izleyen bölümlerde daha ayrıntılı olarak açıklanmıştır. Always Encrypted'ı kullanmak için yalnızca bir anahtar deposu sağlayıcısı uygulamanız gerekir.
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 uygulamanız Azure'da barındırılıyorsa). SQL Server için Microsoft JDBC Sürücüsü, Azure Key Vault'ta depolanan anahtarları olan uygulamalar için SQLServerColumnEncryptionAzureKeyVaultProvideryerleşik bir sağlayıcı içerir. Bu sağlayıcının adı AZURE_KEY_VAULT.
Not
JDBC sürücüsüne yerleşik Azure Key Vault sağlayıcısı, Azure Key Vault 'de hemKasalarını hem de Yönetilen HSM'leri destekler.
Azure Key Vault depolama sağlayıcısını kullanmak için bir uygulama geliştiricisinin Azure Key Vault'ta kasayı ve anahtarları oluşturması ve Microsoft Entra ID (eski adıyla Azure Active Directory) içinde bir Uygulama kaydı oluşturması gerekir. Kayıtlı uygulamaya Always Encrypted ile kullanılmak üzere oluşturulan anahtar kasası için tanımlanan Erişim ilkelerinde Get, Decrypt, Encrypt, Unwrap Key, Wrap Key ve Verify izinleri verilmelidir. Anahtar kasasını ayarlama ve sütun ana anahtarı oluşturma hakkında daha fazla bilgi için bkz. Azure Key Vault— Adım Adım ve Azure Key Vault'ta Sütun Ana Anahtarları Oluşturma.
Azure Key Vault sağlayıcısı için JDBC sürücüsü, sütun ana anahtar yolunu güvenilen uç noktalar listesinde doğrular. 8.2.2 sürümünden itibaren bu liste yapılandırılabilir: uygulamanın çalışma dizininde bir mssql-jdbc.properties dosyası oluşturun, AKVTrustedEndpoints özelliğini noktalı virgülle ayrılmış bir liste olarak ayarlayın. Değer noktalı virgülle başlıyorsa, varsayılan listeyi genişletir. Aksi takdirde, varsayılan listenin yerini alır.
Varsayılan, güvenilen uç noktalar şunlardır:
*vault.azure.net*vault.azure.cn*vault.usgovcloudapi.net*vault.microsoftazure.de-
*managedhsm.azure.net(v9.2+) -
*managedhsm.azure.cn(v9.2+) -
*managedhsm.usgovcloudapi.net(v9.2+) -
*managedhsm.microsoftazure.de(v9.2+)
Bu sayfadaki örneklerde, SQL Server Management Studio ile Azure Key Vault tabanlı bir sütun ana anahtarı ve sütun şifreleme anahtarı oluşturduysanız, bunları yeniden oluşturmak için kullanılan T-SQL betiği kendi özel KEY_PATH ve ENCRYPTED_VALUEile bu örneğe benzer görünebilir:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'AZURE_KEY_VAULT',
KEY_PATH = N'https://<MyKeyVaultName>.vault.azure.net:443/keys/Always-Encrypted-Auto1/c61f01860f37302457fa512bb7e7f4e8'
);
CREATE COLUMN ENCRYPTION KEY [MyCEK]
WITH VALUES
(
COLUMN_MASTER_KEY = [MyCMK],
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x01BA000001680074507400700073003A002F002F006400610076006...
);
JDBC sürücüsünü kullanan bir uygulama Azure Key Vault kullanabilir. Azure Key Vault'un bu kullanımına yönelik söz dizimi veya deyimleri JDBC sürücü sürümü 7.4.1 ile değiştirilmiştir.
JDBC sürücüsü 7.4.1 veya üzeri
Bu bölüm JDBC sürücü sürümü 7.4.1 veya üzerini içerir.
JDBC sürücüsünü kullanan bir istemci uygulaması, JDBC bağlantı dizesine keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey> ekleyerek Azure Key Vault'u kullanacak şekilde yapılandırılabilir.
Burada, bir JDBC bağlantı dizesinde bu yapılandırma bilgilerini sağlayan bir örnek verilmiştir.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>";
JDBC sürücüsü, bağlantı özellikleri arasında bu kimlik bilgileri mevcut olduğunda otomatik olarak bir SQLServerColumnEncryptionAzureKeyVaultProvider nesnesi oluşturur.
Önemli
keyVaultProviderClientId ve keyVaultProviderClientKey bağlantı özellikleri v8.4.1 itibarıyla kullanım dışı bırakılmıştır. Kullanıcıların bunun yerine keyStoreAuthentication, KeyStorePrincipalIdve KeyStoreSecret kullanmaları tavsiye edilir.
7.4.1 öncesi JDBC sürücü sürümleri
Bu bölüm, 7.4.1'in önceki JDBC sürücü sürümlerini içerir.
JDBC sürücüsünü kullanan bir istemci uygulamasının bir SQLServerColumnEncryptionAzureKeyVaultProvider nesnesi örneği oluşturması ve ardından nesneyi sürücüye kaydetmesi gerekir.
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
clientID, Microsoft Entra kiracısında uygulama kaydının Uygulama Kimliğidir.
clientKey, Azure Key Vault'a API erişimi sağlayan, söz konusu Uygulama altında kayıtlı bir Anahtar Parolasıdır.
Uygulama bir SQLServerColumnEncryptionAzureKeyVaultProviderörneği oluşturduğunda, uygulamanın örneği sürücüye SQLServerConnection.registerColumnEncryptionKeyStoreProviders() yöntemiyle kaydetmesi gerekir. Örneğin, SQLServerColumnEncryptionAzureKeyVaultProvider.getName() API tarafından elde edilebilen varsayılan arama adı AZURE_KEY_VAULT kullanılarak kaydedilmesi kesinlikle önerilir. Varsayılan ad, Always Encrypted anahtarları sağlamak ve yönetmek için SQL Server Management Studio veya PowerShell gibi araçları kullanmanıza olanak tanır (araçlar, meta veri nesnesini sütun ana anahtarına oluşturmak için varsayılan adı kullanır). Aşağıdaki örnekte Azure Key Vault sağlayıcısının kaydedilmesi gösterilmektedir.
SQLServerConnection.registerColumnEncryptionKeyStoreProviders() yöntemi hakkında daha fazla bilgi için bkz. JDBC Sürücüsüiçin Always Encrypted API Başvurusu.
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Önemli
Azure Key Vault anahtar deposu sağlayıcısını kullanıyorsanız JDBC sürücüsünün Azure Key Vault uygulaması, uygulamanızla birlikte eklenmesi gereken bu kitaplıklara (GitHub'dan) bağımlılıkları vardır:
"Microsoft Authentication Library for Java" kitaplıkları
Bu bağımlılıkların bir Maven projesine nasıl dahil olduğunu gösteren bir örnek için bkz. Apache Maven ile MSAL4J ve AKV Bağımlılıklarını İndirme
Yönetilen Kimliklerle Azure Key Vault kimlik doğrulamayı kullanma
JDBC Sürücüsü 8.4.1itibarıyla, sürücü Yönetilen Kimliklerle Azure Key Vaults'ta kimlik doğrulaması için destek ekledi.
Uygulama Azure'da barındırılıyorsa Azure Key Vault'ta kimlik doğrulaması yapmak için Yönetilen Kimlikler kullanabilirsiniz. Bu, koddaki kimlik bilgilerini sağlama ve kullanıma sunma gereksinimini ortadan kaldırır.
Yönetilen Kimliklerle Key Vault kimlik doğrulaması için bağlantı özellikleri
JDBC Sürücüsü 8.4.1 ve üzeri için, sürücü aşağıdaki bağlantı özelliklerini kullanıma sunar:
| BağlantıÖzelliği | Olası Değer Eşleştirme 1 | Olası Değer Eşleştirme 2 | Olası Değer Eşleştirme 3 |
|---|---|---|---|
| anahtar deposu kimlik doğrulama | KeyVaultClientSecret | KeyVaultManagedIdentity | Java Anahtar Deposu Şifresi |
| keyStorePrincipalId | <Microsoft Entra Uygulama İstemci Kimliği> | <Microsoft Entra Application nesne kimliği> (isteğe bağlı) | Yok |
| keyStoreSecret | <Microsoft Entra Uygulama İstemci Gizli Anahtarı> | Yok | Java Anahtar Deposu için <parola> |
Aşağıdaki örneklerde bağlantı özelliklerinin bir bağlantı dizesinde nasıl kullanıldığı gösterilmektedir.
AKV'de kimlik doğrulaması yapmak için Yönetilen Kimlik kullanma
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;"
AKV'de kimlik doğrulaması yapmak için Yönetilen Kimlik ve asıl kimliği kullanma
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;keyStorePrincipal=<principalId>"
AKV kimlik doğrulaması için clientId ve clientSecret kullanma
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultClientSecret;keyStorePrincipalId=<clientId>;keyStoreSecret=<clientSecret>"
Kullanıcıların, SQLServerColumnEncryptionAzureKeyVaultProvider API'sinin yerine Anahtar Depoları için kullanılan kimlik doğrulama türünü belirtmek için bu bağlantı özelliklerini kullanmaları tavsiye edilir.
keyVaultProviderClientId ve keyVaultProviderClientKey daha önce eklenen bağlantı özellikleri kullanım dışıdır ve daha önce açıklanan bağlantı özellikleriyle değiştirilir.
Yönetilen Kimlikleri yapılandırma hakkında bilgi için bkz. Azure portalını kullanarak vm üzerinde Azure kaynakları için yönetilen kimlikleri yapılandırma.
Windows Sertifika Deposu sağlayıcısını kullanma
SQLServerColumnEncryptionCertificateStoreProvider, sütun ana anahtarlarını Windows Sertifika Deposu'nda depolamak için kullanılabilir. Veritabanında sütun ana anahtarı ve sütun şifreleme anahtarı tanımlarını oluşturmak için SQL Server Management Studio (SSMS) Always Encrypted sihirbazını veya desteklenen diğer araçları kullanın. Aynı sihirbaz, Windows Sertifika Deposu'nda Always Encrypted verileri için sütun ana anahtarı olarak kullanılabilecek otomatik olarak imzalanan bir sertifika oluşturmak için kullanılabilir. Sütun anahtarı ve sütun şifreleme anahtarı T-SQL söz dizimi hakkında daha fazla bilgi için bkz. sırasıyla CREATE COLUMN MASTER KEY ve CREATE COLUMN ENCRYPTION KEY .
SQLServerColumnEncryptionCertificateStoreProvider adı MSSQL_CERTIFICATE_STORE ve sağlayıcı nesnesinin getName() API'si tarafından sorgulanabilir. Sürücü tarafından otomatik olarak kaydedilir ve herhangi bir uygulama değişikliği olmadan sorunsuz bir şekilde kullanılabilir.
Bu sayfadaki örneklerde, SQL Server Management Studio ile Windows Sertifika Deposu tabanlı bir sütun ana anahtarı ve sütun şifreleme anahtarı oluşturduysanız, bunları yeniden oluşturmak için kullanılan T-SQL betiği kendi özel KEY_PATH ve ENCRYPTED_VALUEile bu örneğe benzer görünebilir:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
KEY_PATH = N'CurrentUser/My/A2A91F59C461B559E4D962DA9D2BC6131B32CB91'
);
CREATE COLUMN ENCRYPTION KEY [MyCEK]
WITH VALUES
(
COLUMN_MASTER_KEY = [MyCMK],
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x016E000001630075007200720065006E0074007500730065007200...
);
Önemli
Bu makaledeki diğer anahtar deposu sağlayıcıları sürücü tarafından desteklenen tüm platformlarda kullanılabilir olsa da, JDBC sürücüsünün SQLServerColumnEncryptionCertificateStoreProvider uygulaması yalnızca Windows işletim sistemlerinde kullanılabilir. Sürücü paketinde bulunan mssql-jdbc_auth-<version>-<arch>.dll'a bir bağımlılık vardır. Bu sağlayıcıyı kullanmak için mssql-jdbc_auth-<version>-<arch>.dll dosyasını JDBC sürücüsünün yüklü olduğu bilgisayardaki Windows sistem yolundaki bir dizine kopyalayın. Alternatif olarak, mssql-jdbc_auth-<version>-<arch>.dlldizinini belirtmek için java.library.path sistem özelliğini ayarlayabilirsiniz. 32 bit Java Sanal Makinesi (JVM) çalıştırıyorsanız, işletim sistemi x64 sürümü olsa bile x86 klasöründeki mssql-jdbc_auth-<version>-x86.dll dosyasını kullanın. x64 işlemcide 64 bit JVM çalıştırıyorsanız x64 klasöründeki mssql-jdbc_auth-<version>-x64.dll dosyasını kullanın. Örneğin, 32 bit JVM kullanırsanız ve JDBC sürücüsü varsayılan dizinde yüklüyse, Java uygulaması başlatıldığında DLL'nin konumunu aşağıdaki sanal makine (VM) bağımsız değişkeniyle belirtebilirsiniz: -Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86
Java Anahtar Deposu sağlayıcısını kullanma
JDBC sürücüsü, Java Anahtar Deposu için yerleşik bir anahtar deposu sağlayıcısı uygulamasıyla birlikte gelir. bağlantı dizesinde keyStoreAuthentication bağlantı dizesi özelliği varsa ve JavaKeyStorePasswordolarak ayarlandıysa, sürücü sağlayıcıyı otomatik olarak oluşturur ve Java Key Store için kaydeder. Java Anahtar Deposu sağlayıcısının adı MSSQL_JAVA_KEYSTORE. Bu ad SQLServerColumnEncryptionJavaKeyStoreProvider.getName() API tarafından da sorgulanabilir.
İstemci uygulamasının, sürücünün Java Anahtar Deposu'nda kimlik doğrulaması yapması için gereken kimlik bilgilerini belirtmesine olanak sağlayan üç bağlantı dizesi özelliği vardır. Sürücü, bağlantı dizesindeki bu üç özelliğin değerlerine göre sağlayıcıyı başlatır.
keyStoreAuthentication: Kullanılacak Java Key Store'u tanımlar. SQL Server için Microsoft JDBC Driver 6.0 ve üzeri sürümlerle Java Anahtar Deposu'nda yalnızca bu özellik aracılığıyla kimlik doğrulaması yapabilirsiniz. Java Anahtar Deposu için bu özelliğin değeri JavaKeyStorePasswordolmalıdır.
keyStoreLocation: Sütun ana anahtarını depolayan Java Anahtar Deposu dosyasının yolu. Yol, keystore dosya adını içerir.
keyStoreSecret: Anahtar deposu ve anahtar için kullanılacak şifre/parola. Java Key Store'u kullanmak için anahtar deposu ve anahtar parolası aynı olmalıdır.
Bağlantı dizesinde bu kimlik bilgilerini sağlama örneği aşağıda verilmiştir:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=<path_to_the_keystore_file>;keyStoreSecret=<keystore_key_password>";
Bu ayarları SQLServerDataSource nesnesiyle de alabilir veya ayarlayabilirsiniz. Daha fazla bilgi için bkz. JDBC Sürücüsü için Always Encrypted API Başvurusu.
JDBC sürücüsü, bu kimlik bilgileri bağlantı özelliklerinde mevcut olduğunda otomatik olarak SQLServerColumnEncryptionJavaKeyStoreProvider oluşturur.
Java Anahtar Deposu için sütun ana anahtarı oluşturma
SQLServerColumnEncryptionJavaKeyStoreProvider JKS veya PKCS12 anahtar deposu türleriyle kullanılabilir. Bu sağlayıcıyla kullanmak üzere bir anahtar oluşturmak veya içeri aktarmak için Java keytool yardımcı programını kullanın. Anahtar, anahtar deposunun kendisiyle aynı parolaya sahip olmalıdır. Burada, keytool yardımcı programıyla ortak anahtar ve ilişkili özel anahtarın nasıl oluşturulacağıyla ilgili bir örnek verilmiştir.
<password> geçerli bir parolayla değiştirin.
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.jks -storepass <password> -validity 360 -keysize 2048 -storetype jks
Bu komut, bir ortak anahtar oluşturur ve bunu ilişkili özel anahtarıyla birlikte, anahtar deposu keystore.jks'da saklanan X.509 kendinden imzalı bir sertifikaya sarar. Anahtar deposundaki bu giriş, AlwaysEncryptedKeytakma adıyla tanımlanır.
PkCS12 mağaza türüyle aynı örneği aşağıda bulabilirsiniz.
<password> geçerli bir parolayla değiştirin.
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.pfx -storepass <password> -validity 360 -keysize 2048 -storetype pkcs12 -keypass <password>
Anahtar deposu PKCS12 türündeyse keytool yardımcı programı anahtar parolası istemez ve anahtar deposu ile anahtarın aynı parolaya sahip olmasını gerektirdiğinden anahtar parolası -keypassSQLServerColumnEncryptionJavaKeyStoreProvider seçeneğiyle sağlanmalıdır.
Ayrıca Windows Sertifika deposundan .pfx biçiminde bir sertifika dışarı aktarabilir ve bunu SQLServerColumnEncryptionJavaKeyStoreProviderile kullanabilirsiniz. Dışarı aktarılan sertifika java anahtar deposuna JKS anahtar deposu türü olarak da aktarılabilir.
Keytool girdisini oluşturduktan sonra, veritabanında anahtar deposu sağlayıcı adı ve anahtar yolu gereken sütun ana anahtar meta verilerini oluşturun. Daha fazla bilgi için, sütun anahtarı meta verisi oluşturma hakkında bkz. CREATE COLUMN MASTER KEY.
SQLServerColumnEncryptionJavaKeyStoreProvideriçin anahtar yolu yalnızca anahtarın diğer adıdır ve SQLServerColumnEncryptionJavaKeyStoreProvider'in adı MSSQL_JAVA_KEYSTORE'dir. Bu adı getName() sınıfının SQLServerColumnEncryptionJavaKeyStoreProvider genel API'siyle de sorgulayabilirsiniz.
Sütun ana anahtarını oluşturmak için T-SQL söz dizimi şöyledir:
CREATE COLUMN MASTER KEY [<CMK_name>]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'<key_alias>'
);
Daha önce oluşturulan 'AlwaysEncryptedKey' için sütun ana anahtar tanımı şöyle olacaktır:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'AlwaysEncryptedKey'
);
Not
Yerleşik SQL Server management Studio işlevi, Java Anahtar Deposu için sütun ana anahtar tanımları oluşturamaz. T-SQL komutları program aracılığıyla kullanılmalıdır.
Java Anahtar Deposu için sütun şifreleme anahtarı oluşturma
SQL Server Management Studio veya başka bir araç, Java Anahtar Deposu'ndaki sütun ana anahtarları kullanılarak sütun şifreleme anahtarları oluşturmak için kullanılamaz. İstemci uygulamasının sütun şifreleme anahtarını SQLServerColumnEncryptionJavaKeyStoreProvider sınıfıyla program aracılığıyla oluşturması gerekir. Daha fazla bilgi için bkz. Programlı anahtar sağlamaiçin sütun ana anahtar deposu sağlayıcılarını kullanma.
Özel sütun anahtar deposu sağlayıcısını uygulamak
Sütun ana anahtarlarını mevcut sağlayıcı tarafından desteklenmeyen bir anahtar deposunda depolamak istiyorsanız, SQLServerColumnEncryptionKeyStoreProvider Sınıfını genişleterek ve sağlayıcıyı aşağıdaki yöntemlerden biriyle kaydederek özel bir sağlayıcı uygulayabilirsiniz:
SQLServerConnection.registerColumnEncryptionKeyStoreProviders-
SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection(JDBC sürüm 10.2'de eklendi) -
SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement(JDBC sürüm 10.2'de eklendi)
public class MyCustomKeyStore extends SQLServerColumnEncryptionKeyStoreProvider{
private String name = "MY_CUSTOM_KEYSTORE";
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public byte[] encryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm, byte[] plainTextColumnEncryptionKey)
{
// Logic for encrypting the column encryption key
}
public byte[] decryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm, byte[] encryptedColumnEncryptionKey)
{
// Logic for decrypting the column encryption key
}
}
Sağlayıcıyı SQLServerConnection.registerColumnEncryptionKeyStoreProvidersile kaydedin:
SQLServerColumnEncryptionKeyStoreProvider storeProvider = new MyCustomKeyStore();
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(storeProvider.getName(), storeProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Sütun şifreleme anahtarı önbellek önceliği
Bu bölüm JDBC sürücü sürümü 10.2 ve üzeri için geçerlidir.
Bir bağlantı veya deyim örneğine kayıtlı özel anahtar deposu sağlayıcıları tarafından şifresi çözülen sütun şifreleme anahtarları (CEK), SQL Server için Microsoft JDBC Sürücüsütarafından önbelleğe alınmaz. Özel anahtar deposu sağlayıcıları kendi CEK önbelleğe alma mekanizmalarını uygulamalıdır.
10.2 sürümünden itibaren SQLServerColumnEncryptionAzureKeyVaultProvider, kendi CEK önbellekleme uygulamasına sahiptir. Bir ilişki veya ifade örneğine kaydedildiğinde, SQLServerColumnEncryptionAzureKeyVaultProvider örneği tarafından şifresi çözülen CEK'ler, bu örnek kapsamın dışına çıktığında temizlenir.
try (SQLServerConnection conn = getConnection(); SQLServerStatement stmt = (SQLServerStatement) conn.createStatement()) {
Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
stmt.registerColumnEncryptionKeyStoreProvidersOnStatement(customKeyStoreProviders);
// Perform database operation with Azure Key Vault Provider
// Any decrypted column encryption keys will be cached
} // Column encryption key cache of "akvProvider" is cleared when "akvProvider" goes out of scope
Not
Özel anahtar deposu sağlayıcıları tarafından uygulanan CEK önbelleğe alma, anahtar deposu sağlayıcı örneği sürücüye genel olarak SQLServerConnection.registerColumnEncryptionKeyStoreProviders yöntemiyle kaydedildiyse sürücü tarafından devre dışı bırakılır. Herhangi bir CEK önbelleğe alma uygulaması, CEK'i önbelleğe almadan önce zaman-aşımı süresi değerine bakmalı ve bu değer sıfır olduğunda önbelleğe almamalıdır. Bu, anahtar önbelleğe almayı yapılandırmaya çalışırken olası kullanıcı karışıklığını ve yinelenen önbelleğe almayı önleyecektir. Önbelleğin yaşam süresi değeri SQLServerColumnEncryptionKeyStoreProvider.setColumnEncryptionCacheTtl yöntemiyle ayarlanabilir.
Özel sütun ana anahtar deposu sağlayıcısını kaydetme
Bu bölüm JDBC sürücü sürümü 10.2 ve üzeri için geçerlidir.
Özel ana anahtar deposu sağlayıcıları sürücüye üç farklı katmanda kaydedilebilir. Üç kaydın önceliği aşağıdaki gibidir:
- İfade başına kayıt boş olup olmadığı kontrol edilir.
- Deyim başına kayıt boşsa, bağlantı başına kayıt boş olup olmadığı kontrol edilir.
- Bağlantı başına kayıt boşsa, genel kayıt kontrol edilir.
Herhangi bir anahtar deposu sağlayıcısı kayıt düzeyinde bulunduktan sonra sürücü DEĞİl sağlayıcı aramak için diğer kayıtlara geri döner. Sağlayıcılar kayıtlıysa ancak uygun sağlayıcı bir düzeyde bulunamazsa, yalnızca denetlenen kayıttaki kayıtlı sağlayıcıları içeren bir özel durum oluşturulur.
Windows Sertifika Deposu için kullanılabilen yerleşik sütun ana anahtar deposu sağlayıcısı önceden kayıtlıdır. Kimlik bilgileri önceden sağlanmışsa, Microsoft Java Keystore sağlayıcısı ve Azure Key Vault Keystore sağlayıcısı kendiliğinden bir bağlantı örneğiyle önceden kaydedilebilir.
Üç kayıt düzeyi, şifrelenmiş verileri sorgularken farklı senaryoları destekler. Bir uygulama kullanıcısının düz metin verilerine erişebildiğinden emin olmak için uygun yöntem kullanılabilir. Şifrelenmemiş verilere erişim, yalnızca gerekli sütun ana anahtarını sağlayabilecekleri durumlarda, sütun ana anahtarını içeren anahtar deposunda kimlik doğrulaması yaparak gerçekleşir.
Bir SQLServerConnection örneğini birden çok kullanıcı arasında paylaşan uygulamalar SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatementkullanmak isteyebilir. Her kullanıcı, şifrelenmiş bir sütuna erişim sağlamak için sorgu yürütmeden önce SQLServerStatement örneğinde bir anahtar deposu sağlayıcısı kaydetmelidir. Anahtar deposu sağlayıcısı, kullanıcının verilen kimlik bilgilerini kullanan anahtar deposunda gerekli sütun ana anahtarına erişebiliyorsa sorgu başarılı olur.
Her kullanıcı için bir SQLServerConnection örneği oluşturan uygulamalar SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnectionkullanmak isteyebilir. Bu yöntemle kaydedilen anahtar deposu sağlayıcıları, şifrelenmiş verilere erişen tüm sorgular için bağlantı tarafından kullanılabilir.
SQLServerConnection.registerColumnEncryptionKeyStoreProviders ile kaydedilen anahtar deposu sağlayıcıları, anahtar deposunda kimlik doğrulaması yaparken uygulama tarafından verilen kimliği kullanır.
Aşağıdaki örnek, bir bağlantı örneğine kayıtlı özel sütun ana anahtar deposu sağlayıcılarının önceliğini gösterir:
Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
MyCustomKeyStore myProvider = new MyCustomKeyStore();
customKeyStoreProviders.put(myProvider.getName(), myProvider);
// Registers the provider globally
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
try (SQLServerConnection conn = getConnection()) {
customKeyStoreProviders.clear();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
// Registers the provider on the connection
// These providers will take precedence over globally registered providers
conn.registerColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);
}
Aşağıdaki örnekte, bir deyim örneğine kayıtlı özel sütun ana anahtar deposu sağlayıcılarının önceliği gösterilmektedir:
Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
MyCustomKeyStore firstProvider = new MyCustomKeyStore();
customKeyStoreProviders.put("FIRST_CUSTOM_STORE", firstProvider);
// Registers the provider globally
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
try (SQLServerConnection conn = getConnection()) {
customKeyStoreProviders.clear();
MyCustomKeyStore secondProvider = new MyCustomKeyStore();
customKeyStoreProviders.put("SECOND_CUSTOM_STORE", secondProvider);
// Registers the provider on the connection
conn.registerColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);
try (SQLServerStatement stmt = (SQLServerStatement) conn.createStatement()) {
customKeyStoreProviders.clear();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
// Registers the provider on the statement
// These providers will take precedence over connection-level providers and globally registered providers
stmt.registerColumnEncryptionKeyStoreProvidersOnStatement(customKeyStoreProviders);
}
}
Programlı anahtar sağlama için sütun ana anahtar deposu sağlayıcılarını kullanma
Şifrelenmiş sütunlara erişmek için SQL Server için Microsoft JDBC Sürü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 olarak bulur ve çağırır. Normal uygulama kodunuz genellikle sütun ana anahtar deposu sağlayıcılarını doğrudan çağırmaz. Ancak Always Encrypted anahtarlarını sağlamak ve yönetmek için program aracılığıyla bir sağlayıcı örneği oluşturabilir ve çağırabilirsiniz. Bu adım, örneğin bir sütun ana anahtarının döndürülmesi işleminin bir parçası olarak, şifrelenmiş bir sütun şifreleme anahtarı oluşturmak ve bir sütun şifreleme anahtarını çözmek için yapılabilir. Daha fazla bilgi için bkz. Always Encryptediçin Anahtar Yönetimine Genel Bakış.
Özel bir anahtar deposu sağlayıcısı kullanıyorsanız, kendi anahtar yönetimi araçlarınızı uygulamak gerekebilir. Windows Sertifika Deposu'nda veya Azure Key Vault'ta depolanan anahtarları kullanmak için, anahtarları yönetmek ve sağlamak için SQL Server Management Studio veya PowerShell gibi mevcut araçları kullanabilirsiniz. Java Key Store'da depolanan anahtarları kullanmak için anahtarları program aracılığıyla sağlamanız gerekir. Aşağıdaki örnekte, anahtarı Java Anahtar Deposu'nda depolanan bir anahtarla şifrelemek için SQLServerColumnEncryptionJavaKeyStoreProvider sınıfının nasıl kullanılacağı gösterilmektedir.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerException;
/**
* This program demonstrates how to create a column encryption key programmatically for the Java Key Store.
*/
public class AlwaysEncrypted {
// Alias of the key stored in the keystore.
private static String keyAlias = "<provide key alias>";
// Name by which the column master key will be known in the database.
private static String columnMasterKeyName = "MyCMK";
// Name by which the column encryption key will be known in the database.
private static String columnEncryptionKey = "MyCEK";
// The location of the keystore.
private static String keyStoreLocation = "C:\\Dev\\Always Encrypted\\keystore.jks";
// The password of the keystore and the key.
private static char[] keyStoreSecret = "<password>".toCharArray();
/**
* Name of the encryption algorithm used to encrypt the value of the column encryption key. The algorithm for the system providers must be
* RSA_OAEP.
*/
private static String algorithm = "RSA_OAEP";
public static void main(String[] args) {
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
try (Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();) {
// Instantiate the Java Key Store provider.
SQLServerColumnEncryptionKeyStoreProvider storeProvider = new SQLServerColumnEncryptionJavaKeyStoreProvider(keyStoreLocation,
keyStoreSecret);
byte[] encryptedCEK = getEncryptedCEK(storeProvider);
/**
* Create column encryption key For more details on the syntax, see:
* https://learn.microsoft.com/sql/t-sql/statements/create-column-encryption-key-transact-sql Encrypted column encryption key first needs
* to be converted into varbinary_literal from bytes, for which byteArrayToHex() is used.
*/
String createCEKSQL = "CREATE COLUMN ENCRYPTION KEY "
+ columnEncryptionKey
+ " WITH VALUES ( "
+ " COLUMN_MASTER_KEY = "
+ columnMasterKeyName
+ " , ALGORITHM = '"
+ algorithm
+ "' , ENCRYPTED_VALUE = 0x"
+ byteArrayToHex(encryptedCEK)
+ " ) ";
statement.executeUpdate(createCEKSQL);
System.out.println("Column encryption key created with name : " + columnEncryptionKey);
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
private static byte[] getEncryptedCEK(SQLServerColumnEncryptionKeyStoreProvider storeProvider) throws SQLServerException {
String plainTextKey = "You need to give your plain text";
// plainTextKey has to be 32 bytes with current algorithm supported
byte[] plainCEK = plainTextKey.getBytes();
// This will give us encrypted column encryption key in bytes
byte[] encryptedCEK = storeProvider.encryptColumnEncryptionKey(keyAlias, algorithm, plainCEK);
return encryptedCEK;
}
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for (byte b : a)
sb.append(String.format("%02x", b).toUpperCase());
return sb.toString();
}
}
Uygulama sorguları için Always Encrypted'i etkinleştirme
Parametrelerin şifrelenmesini ve şifrelenmiş sütunların sorgu sonuçlarının şifresini çözmeyi etkinleştirmenin en kolay yolu, columnEncryptionSetting bağlantı dizesi anahtar sözcüğü değerini Enabledolarak ayarlamaktır.
Aşağıdaki bağlantı dizesi, JDBC sürücüsünde Always Encrypted'i etkinleştirme örneğidir:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;user=<user>;encrypt=true;password=<password>;databaseName=<database>;columnEncryptionSetting=Enabled;";
SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);
Aşağıdaki kod, SQLServerDataSource nesnesini kullanmaya eşdeğer bir örnektir:
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("<server>");
ds.setPortNumber(<port>);
ds.setUser("<user>");
ds.setPassword("<password>");
ds.setDatabaseName("<database>");
ds.setColumnEncryptionSetting("Enabled");
SQLServerConnection con = (SQLServerConnection) ds.getConnection();
Always Encrypted tek tek sorgular için de etkinleştirilebilir. Daha fazla bilgi için bkz. Always Encrypted'nin performans etkisini denetleme. 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
VIEW ANY COLUMN MASTER KEY DEFINITIONveVIEW ANY COLUMN ENCRYPTION KEY DEFINITIONveritabanı izinlerine sahiptir. Ayrıntılar için, Always Encrypted (Veritabanı Altyapısı) İzinlerinebakın. - Uygulama, sorgulanan veritabanı sütunlarını şifreleyen sütun şifreleme anahtarlarını koruyan sütun ana anahtarına erişebilir. Java Anahtar Deposu sağlayıcısını kullanmak için bağlantı dizesinde ek kimlik bilgileri sağlamanız gerekir. Daha fazla bilgi için bkz. Java Anahtar Deposu sağlayıcısını kullanma.
java.sql.Time değerlerinin sunucuya nasıl gönderileceğini yapılandırma
sendTimeAsDatetime bağlantı özelliği, java.sql.Time değerinin sunucuya nasıl gönderileceğini yapılandırmak için kullanılır. false olarak ayarlandığında, zaman değeri SQL Server saat türü olarak gönderilir. True olarak ayarlandığında, saat değeri tarih saat türü olarak gönderilir. Bir zaman sütunu şifrelenirse, şifrelenmiş sütunlar zaman ile tarih ve saat arasında dönüştürmeyi desteklemediği için sendTimeAsDatetime özelliği false olmalıdır. Ayrıca bu özelliğin varsayılan olarak true olduğunu unutmayın, bu nedenle şifrelenmiş zaman sütunlarını kullanmak için false olarak ayarlayın. Aksi takdirde, sürücü bir istisna fırlatır. Sürücünün 6.0 sürümünden başlayarak, SQLServerConnection sınıfının bu özelliğin değerini program aracılığıyla yapılandırmak için iki yöntemi vardır:
- public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
- public boolean getSendTimeAsDatetime()
Bu özellik hakkında daha fazla bilgi için, java.sql.Time değerlerinin sunucuya nasıl gönderileceğini yapılandırma bölümü ,'yı inceleyin.
Dize değerlerinin sunucuya nasıl gönderileceğini yapılandırma
sendStringParametersAsUnicode bağlantı özelliği, Dize değerlerinin SQL Server'a nasıl gönderileceğini yapılandırmak için kullanılır. True olarak ayarlanırsa, Dize parametreleri Sunucuya Unicode biçiminde gönderilir. False olarak ayarlanırsa, Dize parametreleri Unicode yerine Unicode olmayan biçimde (ASCII veya MBCS gibi) gönderilir. Bu özelliğin varsayılan değeri true değeridir. Always Encrypted etkinleştirildiğinde ve bir char/varchar/varchar(max) sütunu şifrelendiğinde, sendStringParametersAsUnicode değeri false olarak ayarlanmalıdır. Bu özellik true olarak ayarlanırsa, sürücü Unicode karakterleri içeren şifrelenmiş bir char/varchar/varchar(max) sütunundaki verilerin şifresini çözerken bir özel durum oluşturur. Bu özellik hakkında daha fazla bilgi için bkz. Bağlantı Özelliklerini Ayarlama.
Önemli
sendStringParametersAsUnicode olarak ayarlanırsa ve Unicode verileri Always Encrypted ile şifrelenmiş bir truechar/ sütuna eklenirse, hata bildirilmeden veri kaybı oluşabilir. Veri kaybı, yalnızca sunucudan geri okunarak şifresi çözülmeye çalışıldığında algılanabilir. sonuç Decryption failed. The last 10 bytes of the encrypted column encryption key are: 'C3-D9-10-4E-C1-45-8B-94-A2-43'. The first 10 bytes of ciphertext are: '01-9B-9D-A6-3E-40-22-53-15-9B'. gibi bir hata olabilir.
Şifrelenmiş veri eklerken doğru sütun veri türlerini kullanmak ve parametreler için doğru veri türünü belirtmek önemlidir. Unicode verileri bekleniyorsa nchar/nvarchar sütunlarını ve setNString() yöntemlerini kullanın. Sunucu örtük veri dönüştürmeleri gerçekleştiremez ve Always Encrypted etkinleştirildiğinde veri hatalarını algılama özelliği sınırlıdır.
Ş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 JDBC API'lerini kullanabilirsiniz. Uygulamanız gerekli veritabanı izinlerine sahipse ve sütun ana anahtarına erişebiliyorsa, sürücü şifrelenmiş sütunları hedefleyen tüm sorgu parametrelerini şifreler ve ş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 yine de şifrelenmiş sütunlardan veri alabilir. Ancak, sürücü ş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ışı özetlenir:
| 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 JDBC 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. |
Şifrelenmiş veri örnekleri ekleme ve alma
Aşağıdaki örneklerde şifrelenmiş sütunlardaki verilerin alınması ve değiştirilmesi gösterilmektedir. Örneklerde hedef tablo aşağıdaki şemaya ve şifrelenmiş SSN ve BirthDate sütunlarına sahip olduğu varsayılır. "MyCMK" adlı bir Sütun Ana Anahtarı ve "MyCEK" adlı bir Sütun Şifreleme Anahtarı yapılandırdıysanız (önceki anahtar deposu sağlayıcıları bölümlerinde açıklandığı gibi), tabloyu şu betikle oluşturabilirsiniz:
CREATE TABLE [dbo].[Patients]([PatientId] [int] IDENTITY(1,1),
[SSN] [char](11) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = MyCEK) NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[BirthDate] [date]
ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = MyCEK) NOT NULL
PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY]);
GO
Her Java kodu örneği için, anahtar deposuna özgü kodu belirtilen konuma eklemeniz gerekir.
Azure Key Vault anahtar deposu sağlayıcısını kullanmak için:
String clientID = "<Azure Application ID>";
String clientKey = "<Azure Application API Key Password>";
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
Windows Sertifika Deposu anahtar deposu sağlayıcısını kullanmak için:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
Java Anahtar Deposu anahtar deposu sağlayıcısını kullanmak için:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=<path to jks or pfx file>;keyStoreSecret=<keystore secret/password>";
Veri ekleme örneği
Bu örnek, Patients tablosuna bir satır ekler. Aşağıdaki öğelere dikkat edin:
- Örnek kodda şifrelemeye özgü bir şey yoktur. SQL Server için Microsoft JDBC Sürücüsü, şifrelenmiş sütunları hedefleyen parametreleri otomatik olarak algılar ve şifreler. Bu davranış, şifrelemeyi uygulama için saydam hale getirir.
- Şifrelenmiş sütunlar da dahil olmak üzere veritabanı sütunlarına eklenen değerler,
SQLServerPreparedStatementile parametre olarak geçirilir. Parametreler, şifrelenmemiş sütunlara değer gönderirken isteğe bağlıdır (ancak SQL eklemenin önlenmesine yardımcı olduğu için kesinlikle önerilir), şifrelenmiş sütunları hedefleyen değerler için gereklidir. Şifrelenmiş sütunlara eklenen değerler sorgu deyimine eklenmiş değişmez değerler olarak geçirildiyse, sürücü hedef şifrelenmiş sütunlardaki değerleri belirleyemediğinden ve değerleri şifrelemediğinden sorgu başarısız olur. Sonuç olarak, sunucu bunları şifrelenmiş sütunlarla uyumsuz olarak reddeder. - SQL Server için Microsoft JDBC Sürücüsü şifrelenmiş sütunlardan 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.
- WHERE yan tümcesiyle arama yapıyorsanız, sürücünün veritabanına göndermeden önce saydam bir şekilde şifreleyebilmesi için WHERE yan tümcesinde kullanılan değerin parametre olarak geçirilmesi gerekir. Aşağıdaki örnekte, "SSN" parametre olarak geçirilir ve "LastName" şifrelenmediğinden "sabit değer" olarak geçirilir.
- SSN sütununu hedefleyen parametre için kullanılan ayarlayıcı yöntemi,
setString()char/ SQL Server veri türüne eşlenenvarcharyöntemidir. Bu parametre için kullanılan ayarlayıcı yöntemi,setNString()nchar/ile eşlenennvarcharyöntemiyse, Always Encrypted şifrelenmişnchar/nvarchardeğerlerinden şifrelenmişchar/varchardeğerlerine dönüştürmeleri desteklemediğinden sorgu başarısız olur.
// <Insert keystore-specific code here>
try (Connection sourceConnection = DriverManager.getConnection(connectionUrl);
PreparedStatement insertStatement = sourceConnection.prepareStatement("INSERT INTO [dbo].[Patients] VALUES (?, ?, ?, ?)")) {
insertStatement.setString(1, "795-73-9838");
insertStatement.setString(2, "Catherine");
insertStatement.setString(3, "Abel");
insertStatement.setDate(4, Date.valueOf("1996-09-10"));
insertStatement.executeUpdate();
System.out.println("1 record inserted.\n");
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Düz metin verisi 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ğıdaki öğelere dikkat edin:
- SSN sütununa filtre uygulamak için WHERE yan tümcesinde kullanılan değerin, SQL Server için Microsoft JDBC Sürücüsü'nin veritabanına göndermeden önce saydam bir şekilde şifreleyebilmesi için parametre olarak geçirilmesi gerekir.
- SQL Server için Microsoft JDBC Sürücüsü SSN ve DoğumTarihi 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.
Not
sütunlar belirleyici şifreleme ile şifrelenirse, sorgular bunlar üzerinde eşitlik karşılaştırmaları gerçekleştirebilir. Daha fazla bilgi için bkz. belirleyici şifreleme.
// <Insert keystore-specific code here>
try (Connection connection = DriverManager.getConnection(connectionUrl);
PreparedStatement selectStatement = connection
.prepareStatement("\"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN = ?;\"");) {
selectStatement.setString(1, "795-73-9838");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("SSN: " + rs.getString("SSN") + ", FirstName: " + rs.getString("FirstName") + ", LastName:"
+ rs.getString("LastName") + ", Date of Birth: " + rs.getString("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Şifrelenmiş verileri alma ö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 örnekte şifrelenmiş sütunlardan ikili şifrelenmiş verilerin alınması gösterilmektedir. Aşağıdaki öğelere 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. Aşağı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.
try (Connection sourceConnection = DriverManager.getConnection(connectionUrl);
PreparedStatement selectStatement = sourceConnection
.prepareStatement("SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE LastName = ?;");) {
selectStatement.setString(1, "Abel");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("SSN: " + rs.getString("SSN") + ", FirstName: " + rs.getString("FirstName") + ", LastName:"
+ rs.getString("LastName") + ", Date of Birth: " + rs.getString("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Şifrelenmiş sütunları sorgularken sık karşılaşılan sorunlardan kaçınma
Bu bölümde, Java 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 (Veritabanı Altyapısı) . Veri türü dönüştürme hatalarını önlemek için şunları yapabilirsiniz. Şu şekilde olduğundan emin olun:
şifrelenmiş sütunları hedefleyen parametreler için değerleri geçirirken uygun ayarlayıcı yöntemlerini kullanırsınız. Parametrenin SQL Server veri türünün hedef sütunun türüyle tam olarak aynı olduğundan veya parametrenin SQL Server veri türünün sütunun hedef türüne dönüştürülmesinin desteklendiğinden emin olun. API yöntemleri, belirli SQL Server veri türlerine karşılık gelen parametreleri geçirmek için
SQLServerPreparedStatement,SQLServerCallableStatementveSQLServerResultSetsınıflarına eklenmiştir. Yeni API'lerin tam listesi için, JDBC Sürücüsü için Always Encrypted API Başvurusubölümüne bakın. Veri türü tanımlarına uymamak büyük olasılıkla işlenen türü çakışma hatalarına neden olur. Always Encrypted kullanılırken gerekli olabilecek bazı ayarlama örnekleri aşağıda verilmiştir:-
setTimestamp()yöntemini kullanarak bir parametreyi şifrelenmemiş bir datetime2 veya datetime sütununa geçirebilirsiniz. Ancak bir sütun şifrelendiğinde, veritabanındaki sütunun türünü temsil eden tam yöntemi kullanmanız gerekir. Değerleri şifrelenmiş bir datetime2 sütununa geçirmek içinsetTimestamp()kullanın ve değerleri şifrelenmiş bir tarih saat sütununa geçirmek içinsetDateTime()kullanın. -
setBinary()yöntemini kullanarak bir parametreyi şifrelenmemiş birvarbinary(max)veyabinarysütununa geçirebilirsiniz. Sürücü varsayılan olarakBINARYparametreleri içinsetBinary()veri türünü kullanır ve sunucu verileri örtük olarak birvarbinary(max)sütununa eklemek üzere dönüştürebilir. Ancak birvarbinary(max)sütunu şifrelendiğinde parametre verileri için daha kesin bir tür belirtmeniz gerekir. Örnek:preparedStatement.setObject(1, binaryData, java.sql.JDBCType.LONGVARBINARY)
-
ondalık ve sayısal SQL Server veri türlerinin sütunlarını hedefleyen parametrelerin duyarlığı ve ölçeği, hedef sütun için yapılandırılan duyarlık ve ölçekle aynıdır. API yöntemleri, ondalık ve sayısal veri türlerini temsil eden parametreler/sütunlar için veri değerleriyle birlikte duyarlık ve ölçeklendirmeyi kabul etmek için
SQLServerPreparedStatement,SQLServerCallableStatementveSQLServerResultSetsınıflarına eklenmiştir. Yeni/aşırı yüklenmiş API'lerin tam listesi için bkz. JDBC Sürücüsü için Always Encrypted API Başvurusu.- Örneğin, Java'nın
BigDecimalparametre türünü veritabanında belirtilen ondalık sütunu hedeflemek için kullandığınızda, duyarlık ve ölçeğisetBigDecimal()yöntemine veyasetValue()yöntemine sağlamanız gerekir. Doğru duyarlık ve ölçek belirtilememesi aşağıdaki gibi bir hataya neden olabilir:
Operand type clash: decimal(18,0) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'myCek', column_encryption_key_database_name = 'issue2169') is incompatible with decimal(20,4) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'myCek', column_encryption_key_database_name = 'myDatabase')- Örneğin, Java'nın
datetime2,datetimeoffsetveya zaman SQL Server veri türlerinin sütunlarını hedefleyen parametrelerin kesirli saniye duyarlığı/ölçeği, hedef sütunun değerlerini değiştiren sorgularda hedef sütun için kesirli saniye duyarlığı/ölçeğinden büyük değildir. API yöntemleri,SQLServerPreparedStatement,SQLServerCallableStatementveSQLServerResultSetsınıflarına eklenerek kesirli saniye duyarlık/ölçek ile bu veri türlerini temsil eden parametreler için veri değerlerini kabul eder. Yeni/aşırı yüklenmiş API'lerin tam listesi için JDBC Sürücüsü için Always Encrypted API Referansına bakın.
Yanlış bağlantı özelliklerinden kaynaklanan hatalar
Bu bölümde, Always Encrypted verilerini kullanmak için bağlantı ayarlarının nasıl düzgün yapılandırıldığı açıklanmaktadır. Şifrelenmiş veri türleri sınırlı dönüştürmeleri desteklediğinden, sendTimeAsDatetime ve sendStringParametersAsUnicode bağlantı ayarlarının şifrelenmiş sütunları kullanmak için uygun yapılandırmaya ihtiyacı vardır. Şu şekilde olduğundan emin olun:
- sendTimeAsDatetime bağlantı ayarı, şifrelenmiş zaman sütunlarına veri eklenirken false olarak ayarlanır. Daha fazla bilgi için bkz. java.sql.Time Değerlerininsunucuya nasıl gönderileceğini yapılandırma.
- sendStringParametersAsUnicode bağlantı ayarı, şifrelenmiş char/varchar/varchar(max) sütunlarına veri eklerken true (veya varsayılan olarak bırakılır) olarak ayarlanır.
Ş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:
com.microsoft.sqlserver.jdbc.SQLServerException: Operand type clash: varchar is incompatible with varchar(8000) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'MyCEK', column_encryption_key_database_name = 'ae') collation_name = 'SQL_Latin1_General_CP1_CI_AS'
Bu tür hataları önlemek için şunlardan emin olun:
- Always Encrypted, şifrelenmiş sütunları hedefleyen uygulama sorguları (bağlantı dizesi veya belirli bir sorgu için) için etkinleştirilir.
- şifrelenmiş sütunları hedefleyen verileri göndermek için hazırlanmış deyimleri ve parametreleri kullanırsınız. Aşağıdaki örnekte, sabit değeri parametre olarak içine geçirmek yerine şifrelenmiş bir sütunda (SSN) sabit/değişmez değere göre yanlış filtreleyen bir sorgu gösterilmektedir. Bu sorgu başarısız olur:
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM Customers WHERE SSN='795-73-9838'");
Giriş parametrelerinde şifrelemeyi zorlama
Şifrelemeyi Zorla özelliği, Always Encrypted ile bir parametrenin şifrelenmesini zorunlu kılar. Zorlamalı şifreleme kullanılırsa ve 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.
SQLServerPreparedStatement ve SQLServerCallableStatement sınıflarındaki set* yöntemleri ve update* sınıfındaki SQLServerResultSet yöntemleri, zorlamalı şifreleme ayarını belirtmek üzere boole bağımsız değişkenini kabul etmek için aşırı yüklenir. Bu bağımsız değişkenin değeri false ise, sürücü parametrelerde şifrelemeyi zorlamaz. Zorlamalı şifreleme true olarak ayarlanırsa, sorgu parametresi yalnızca hedef sütun şifrelenmişse ve Always Encrypted bağlantıda veya deyimde etkinse gönderilir. Bu özellik ek bir güvenlik katmanı sağlayarak sürücünün şifrelenmesi beklendiğinde sql Server'a yanlışlıkla düz metin olarak veri göndermemesini sağlar.
Zorlamalı şifreleme ayarıyla aşırı yüklenmiş SQLServerPreparedStatement ve SQLServerCallableStatement yöntemleri hakkında daha fazla bilgi için bkz. JDBC Sürücüsü için Always Encrypted API Başvurusu
Always Encrypted'ın performans etkisini denetleme
Always Encrypted bir istemci tarafı şifreleme teknolojisi olduğundan, performans ek yükünün ç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 gidiş dönüşler eklendi.
- 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 Microsoft JDBC Sürücüsü'ndeki yerleşik performans iyileştirmeleri ve daha önce bahsedilen 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ştirilirse, sürücü varsayılan olarak her parametreli sorgu için sys.sp_describe_parameter_encryption çağırır ve sorgu deyimini (parametre değerleri olmadan) veritabanına geçirir. sys.sp_describe_parameter_encryption, herhangi bir parametrenin şifrelenmesi gerekip gerekmediğini öğrenmek için sorgu deyimini analiz eder ve gerekiyorsa her biri için sürücünün parametre değerlerini şifrelemesine olanak tanıyan şifrelemeyle ilgili bilgileri döndürür. Bu davranış, istemci uygulaması için yüksek düzeyde saydamlık sağlar. Uygulama, şifrelenmiş sütunları hedefleyen değerleri sürücüye geçirmek için parametreler kullandığı sürece, uygulamanın (ve uygulama geliştiricisinin) şifrelenmiş sütunlara erişen sorguları bilmesi gerekmez.
Always Encrypted'i sorgu düzeyinde ayarlama
Parametreli sorgular için şifreleme meta verilerini almanın performans 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 şifrelemenin 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.
Tek tek sorguların Always Encrypted davranışını denetlemek için, söz konusu deyim için şifrelenmiş sütunları okurken ve yazarken verilerin nasıl gönderileceğini ve alınacağını belirten SQLServerStatementColumnEncryptionSetting adlı bir Enum geçirerek tek tek deyim nesnelerini yapılandırmanız gerekir. Bazı yararlı yönergeler şunlardır:
İstemci uygulaması, çoğu sorgusunu veritabanı bağlantısı üzerinden şifreli sütunlara erişim için gönderiyorsa, bu adımları izleyin:
-
columnEncryptionSettingbağlantı dizesi anahtar sözcüğünüEnabledolarak ayarlayın. - Şifrelenmiş sütunlara erişmeyen tek tek sorgular için
SQLServerStatementColumnEncryptionSetting.Disabledayarlayın. Bu ayar hemsys.sp_describe_parameter_encryptionçağırmayı hem de sonuç kümesindeki değerlerin şifresini çözmeyi devre dışı bırakır. - Şifreleme gerektiren parametreleri olmayan ancak şifrelenmiş sütunlardan veri alan tek tek sorgular için
SQLServerStatementColumnEncryptionSetting.ResultSetayarlayın. Bu ayar,sys.sp_describe_parameter_encryptionve parametre şifreleme çağrılarını devre dışı bırakır. Sorgu, sonuçların şifresini şifreleme sütunlarından çözer.
-
bir istemci uygulamasının veritabanı bağlantısı üzerinden gönderdiği sorguların çoğu şifrelenmiş sütunlara erişmiyorsa şu yönergeleri kullanın:
-
columnEncryptionSettingbağlantı dizesi anahtar sözcüğünüDisabledolarak ayarlayın. - Şifrelenmesini gerektiren parametreleri olan tek tek sorgular için
SQLServerStatementColumnEncryptionSetting.Enabledayarlayın. Bu ayar, hemsys.sp_describe_parameter_encryption'ın çağrılmasını hem de şifrelenmiş sütunlardan alınan sorgu sonuçlarının şifresinin çözülmesini etkinleştirir. - Şifreleme gerektiren parametreleri olmayan ancak şifrelenmiş sütunlardan veri alan sorgular için
SQLServerStatementColumnEncryptionSetting.ResultSetayarlayın. Bu ayar,sys.sp_describe_parameter_encryptionve parametre şifreleme çağrılarını devre dışı bırakır. Sorgu, sonuçların şifresini şifreleme sütunlarından çözer.
-
SQLServerStatementColumnEncryptionSetting ayarları şifrelemeyi atlamak ve düz metin verilerine erişmek için kullanılamaz. Bir deyimde sütun şifrelemesini yapılandırma hakkında daha fazla bilgi için bkz. JDBC Sürücüsüiçin Always Encrypted API Başvurusu.
Aşağıdaki örnekte, veritabanı bağlantısı için Always Encrypted devre dışı bırakılmıştır. Uygulamanın oluşturduğu sorguda, şifrelenmemiş LastName sütununu hedefleyen bir parametre vardır. 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ğrılması gerekmez. 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.
SQLServerStatementColumnEncryptionSetting.ResultSet ayarı, bunu sağlamak için kullanılır.
// Assumes the same table definition as in Section "Retrieving and modifying data in encrypted columns"
// where only SSN and BirthDate columns are encrypted in the database.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<database>;user=<user>;password=<password>;"
+ "keyStoreAuthentication=JavaKeyStorePassword;"
+ "keyStoreLocation=<keyStoreLocation>"
+ "keyStoreSecret=<keyStoreSecret>;";
String filterRecord = "SELECT FirstName, LastName, SSN, BirthDate FROM " + tableName + " WHERE LastName = ?";
try (SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);
PreparedStatement selectStatement = connection.prepareStatement(filterRecord, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
connection.getHoldability(), SQLServerStatementColumnEncryptionSetting.ResultSetOnly);) {
selectStatement.setString(1, "Abel");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("First name: " + rs.getString("FirstName"));
System.out.println("Last name: " + rs.getString("LastName"));
System.out.println("SSN: " + rs.getString("SSN"));
System.out.println("Date of Birth: " + rs.getDate("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Sorgu parametresi meta verileri önbelleğe alma
Veritabanına gidiş dönüş sayısını azaltmak için, SQL Server için Microsoft JDBC Sürücüsü sorgu parametreleri için şifrelemeyle ilgili bilgileri önbelleğe alabilir. Sürüm 11.2.0'dan itibaren, ilişkili SQL Server işlemi güvenli kuşatmalar kullanmıyorsa, sys.sp_describe_parameter_encryption çağrılarından döndürülen parametreler için şifrelemeyle ilgili bilgiler sürücü tarafından önbelleğe alınır. Güvenli bölgelerin kullanımıyla önbelleğe almak için, oturumun artık geçerli olmadığı durumlarda sunucunun güvenli bölge oturumunu yeniden oluşturmayı desteklemesi gerekir.
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 Microsoft JDBC Sürücüsü düz metin sütun şifreleme anahtarlarını bellekte önbelleğe alır. Sürücü, 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. Önbellekte şifrelenmiş sütun şifreleme anahtarı değerini bulamazsa, sürücü yalnızca sütun ana anahtarını içeren keystore'u çağırır.
setColumnEncryptionKeyCacheTtl() sınıfında SQLServerConnectionAPI ile önbellekteki sütun şifreleme anahtarı girişleri için yaşam süresi değeri yapılandırabilirsiniz. Önbellekteki sütun şifreleme anahtarı girişleri için varsayılan yaşam süresi değeri iki saattir. Önbelleğe almayı kapatmak için 0 değerini kullanın. Yaşam süresi değerini ayarlamak için aşağıdaki API'yi kullanın:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (int columnEncryptionKeyCacheTTL, TimeUnit unit)
Örneğin, yaşam süresi değerini 10 dakika olarak ayarlamak için şunu kullanın:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (10, TimeUnit.MINUTES)
Zaman birimi olarak yalnızca DAYS, HOURS, MINUTES veya SECONDS desteklenir.
SQLServerBulkCopy ile şifrelenmiş verileri kopyalama
SQLServerBulkCopyile, 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. Herhangi bir hedef sütun karşılık gelen kaynak sütunundan farklı şekilde şifrelenirse, kopyalama işleminden sonra hedef tablodaki verilerin şifresini çözemezsiniz. Veriler bozulur.
- Always Encrypted etkinleştirilmeden hem kaynak tabloya hem de hedef tabloya veritabanı bağlantılarını yapılandırın.
-
allowEncryptedValueModificationsseçeneğini ayarlayın. Daha fazla bilgi için bkz. JDBC sürücüsüyle toplu kopyalama kullanma.
Not
AllowEncryptedValueModifications seçeneğini belirtirken dikkatli olun çünkü Microsoft JDBC Sürücüsü, SQL Server için verilerin gerçekten şifrelenip şifrelenmediğini veya hedef sütunla aynı şifreleme türü, algoritma ve anahtarla doğru şekilde şifrelenip şifrelenmediğini kontrol etmez, bu da veritabanının bozulmasına yol açabilir.