Použití funkce Always Encrypted s ovladačem JDBC
Tato stránka obsahuje informace o tom, jak vyvíjet aplikace Java pro použití Always Encrypted s ovladačem Microsoft JDBC 6.0 (nebo novějším) pro SQL Server.
Funkce Always Encrypted umožňuje klientům šifrovat citlivá data a nikdy nezoradit data nebo šifrovací klíče pro SQL Server nebo Azure SQL Database. Ovladač s povolenou funkcí Always Encrypted, například Ovladač Microsoft JDBC 6.0 (nebo vyšší) pro SQL Server, dosahuje tohoto chování transparentním šifrováním a dešifrováním citlivých dat v klientské aplikaci. Ovladač zjistí, které parametry dotazu odpovídají sloupcům databáze Always Encrypted, a před jejich odesláním do databáze zašifruje hodnoty těchto parametrů. Ovladač podobně transparentně dešifruje data načtená ze šifrovaných databázových sloupců ve výsledcích dotazu. Další informace naleznete v tématu Always Encrypted (databázový stroj) a Always Encrypted API reference pro ovladač JDBC.
Požadavky
- Ujistěte se, že je na vývojovém počítači nainstalovaný ovladač Microsoft JDBC 6.0 (nebo novější) pro SQL Server.
- Stáhněte a nainstalujte soubory zásad Java Cryptography Extension (JCE) Neomezená síla jurisdikční politiky. Nezapomeňte si přečíst soubor Readme, který je součástí souboru ZIP, pokyny k instalaci a relevantní podrobnosti o možných problémech s exportem nebo importem.
- Pro mssql-jdbc-X.X.X.jre7.jar nebo sqljdbc41.jar lze stáhnout soubory zásad z Java Cryptography Extension (JCE) Soubory zásad pro neomezenou sílu šifrování Jurisdiction 7 Download
- Pro mssql-jdbc-X.X.X.jre8.jar nebo sqljdbc42.jar lze soubory zásad stáhnout z Java Cryptography Extension (JCE) Neomezené soubory zásad silné jurisdikce 8 Stáhnout
- Pro libovolnou verzi JRE verze 9 nebo novější (například mssql-jdbc-X.X.X.jre9.jar) není potřeba stáhnout žádný soubor zásad. Politika jurisdikce v Javě 9 a vyšších má ve výchozím nastavení šifrování s neomezenou silou.
Práce s úložišti klíčů pro hlavní sloupce
Pokud chcete šifrovat nebo dešifrovat data pro šifrované sloupce, SQL Server udržuje šifrovací klíče sloupců. Šifrovací klíče sloupců jsou uloženy v šifrované podobě v metadatech databáze. Každý šifrovací klíč sloupce má odpovídající hlavní klíč sloupce, který slouží k šifrování šifrovacího klíče sloupce.
Metadata databáze neobsahují hlavní klíče sloupců. Tyto klíče jsou uloženy pouze klientem. Metadata databáze ale obsahují informace o tom, kde jsou hlavní klíče sloupců uloženy vzhledem k klientovi. Například metadata databáze můžou říkat úložiště klíčů, které obsahuje hlavní klíč sloupce, je Úložiště certifikátů systému Windows a konkrétní certifikát, který se používá k šifrování a dešifrování, se nachází v určité cestě v rámci služby Windows Certificate Store.
Pokud má klient přístup k certifikátu v úložišti certifikátů ve Windows, může certifikát získat. Certifikát pak můžete použít k dešifrování šifrovacího klíče sloupce. Potom lze tento šifrovací klíč použít k dešifrování nebo šifrování dat pro šifrované sloupce, které využívají tento klíč pro šifrování sloupců.
Ovladač Microsoft JDBC pro SQL Server komunikuje s úložištěm klíčů, který používá zprostředkovatele úložiště klíčů hlavního sloupce, což je instance třídy odvozené z SQLServerColumnEncryptionKeyStoreProvider
.
Použití předdefinovaných zprostředkovatelů úložiště klíčů hlavního sloupce
Ovladač Microsoft JDBC pro SQL Server se dodává s následujícími integrovanými zprostředkovateli úložiště klíčů hlavního sloupce. Někteří z těchto poskytovatelů jsou předem registrovaní s konkrétními názvy (které slouží k identifikaci poskytovatele) a někteří vyžadují buď další přihlašovací údaje, nebo explicitní registraci.
Třída | Popis | Název zprostředkovatele (vyhledávání) | Je předregistrováno? | Platforma |
---|---|---|---|---|
SQLServerColumnEncryptionAzureKeyVaultProvider |
Zprostředkovatel úložiště klíčů pro Azure Key Vault. | Azure Key Vault | Ne před verzí 7.4.1 ovladače JDBC, ale ano od verze 7.4.1 ovladače JDBC. | Windows, Linux, macOS |
SQLServerColumnEncryptionCertificateStoreProvider |
Zprostředkovatel úložiště certifikátů systému Windows. | MSSQL_CERTIFICATE_STORE | Ano | Windows |
SQLServerColumnEncryptionJavaKeyStoreProvider |
Zprostředkovatel úložiště klíčů Java. | MSSQL_JAVA_KEYSTORE | Ano | Windows, Linux, macOS |
U předregistrovaných zprostředkovatelů úložiště klíčů nepotřebujete k použití těchto zprostředkovatelů žádné změny kódu aplikace, ale všimněte si následujících položek:
- Musíte se ujistit, že název zprostředkovatele nakonfigurovaný v metadatech hlavního klíče sloupce je správný a cesta hlavního klíče sloupce se řídí formátem cesty klíče, který je platný pro daného zprostředkovatele. Doporučujeme nakonfigurovat klíče pomocí nástrojů, jako je SQL Server Management Studio, které automaticky vygeneruje platné názvy zprostředkovatelů a cesty klíčů k vydání příkazu
CREATE COLUMN MASTER KEY
(Transact-SQL). - Ujistěte se, že vaše aplikace má přístup k klíči v úložišti klíčů. Tato úloha může zahrnovat udělení přístupu aplikace ke klíči nebo úložišti klíčů. V závislosti na úložištích klíčů to může zahrnovat další kroky specifické pro konfiguraci úložiště klíčů. Pokud například chcete použít
SQLServerColumnEncryptionJavaKeyStoreProvider
, musíte zadat umístění a heslo úložiště klíčů ve vlastnostech připojení.
Všichni tito poskytovatelé úložiště klíčů jsou podrobněji popsáni v následujících částech. K použití funkce Always Encrypted stačí implementovat pouze jednoho zprostředkovatele úložiště klíčů.
Použití zprostředkovatele služby Azure Key Vault
Azure Key Vault je pohodlná možnost ukládat a spravovat hlavní klíče sloupců pro Always Encrypted (zejména pokud je vaše aplikace hostovaná v Azure). Ovladač Microsoft JDBC pro SQL Server obsahuje integrovaného poskytovatele SQLServerColumnEncryptionAzureKeyVaultProvider
pro aplikace, které mají klíče uložené ve službě Azure Key Vault. Název tohoto poskytovatele je AZURE_KEY_VAULT.
Poznámka
Zprostředkovatel služby Azure Key Vault integrovaný v ovladači JDBC podporuje Trezory i spravované HSM ve službě Azure Key Vault.
Aby vývojář aplikace mohli používat poskytovatele úložiště Azure Key Vault, musí vytvořit trezor a klíče ve službě Azure Key Vault a vytvořit registraci aplikace v Microsoft Entra ID (dříve Azure Active Directory). Registrovaná aplikace musí mít udělená oprávnění Get, Decrypt, Encrypt, Unwrap Key, Wrap Key a Verify v zásadách přístupu definovaných pro trezor klíčů vytvořený pro použití s funkcí Always Encrypted. Další informace o nastavení trezoru klíčů a vytvoření hlavního klíče sloupce najdete v tématu Azure Key Vault – krok za krokem a Vytvoření hlavních klíčů sloupců ve službě Azure Key Vault.
U poskytovatele služby Azure Key Vault ovladač JDBC ověří cestu hlavního klíče sloupce v seznamu důvěryhodných koncových bodů. Od verze 8.2.2 je tento seznam konfigurovatelný: v pracovním adresáři aplikace vytvořte soubor mssql-jdbc.properties
, nastavte vlastnost AKVTrustedEndpoints
na seznam oddělený středníkem. Pokud hodnota začíná středníkem, rozšíří se výchozí seznam. V opačném případě nahradí výchozí seznam.
Výchozí důvěryhodné koncové body jsou:
*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+)
Pokud jste pomocí aplikace SQL Server Management Studio vytvořili hlavní klíč a šifrovací klíč sloupce založené na Azure Key Vault, skript T-SQL pro jejich opětovné vytvoření může vypadat podobně jako v tomto příkladu s vlastními konkrétními KEY_PATH a ENCRYPTED_VALUE:
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...
);
Aplikace, která používá ovladač JDBC, může používat službu Azure Key Vault. Syntaxe nebo příkazy pro toto použití služby Azure Key Vault se změnily od ovladače JDBC verze 7.4.1.
Ovladač JDBC 7.4.1 nebo novější
Tato část zahrnuje ovladač JDBC verze 7.4.1 nebo novější.
Klientská aplikace, která používá ovladač JDBC, může nakonfigurovat použití služby Azure Key Vault tak, že zmíní keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>
v připojovacím řetězci JDBC.
Tady je příklad, který poskytuje tyto konfigurační informace v připojovacím řetězci JDBC.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>";
Ovladač JDBC automaticky vytvoří instanci objektu SQLServerColumnEncryptionAzureKeyVaultProvider
, pokud jsou tyto přihlašovací údaje přítomny mezi vlastnostmi připojení.
Důležitý
Vlastnosti připojení keyVaultProviderClientId
a keyVaultProviderClientKey
byly vyřazeny od verze 8.4.1. Uživatelům se doporučuje místo toho používat keyStoreAuthentication
, KeyStorePrincipalId
a KeyStoreSecret
.
Verze ovladače JDBC starší než 7.4.1
Tato část zahrnuje verze ovladače JDBC starší než 7.4.1.
Klientská aplikace, která používá ovladač JDBC, musí vytvořit instanci objektu SQLServerColumnEncryptionAzureKeyVaultProvider
a pak objekt zaregistrovat u ovladače.
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
clientID
je ID registrace aplikace v tenant Microsoft Entra.
clientKey
je heslo klíče zaregistrované v této aplikaci, které poskytuje přístup rozhraní API ke službě Azure Key Vault.
Jakmile aplikace vytvoří instanci SQLServerColumnEncryptionAzureKeyVaultProvider
, musí aplikace zaregistrovat instanci s ovladačem pomocí metody SQLServerConnection.registerColumnEncryptionKeyStoreProviders()
. Důrazně doporučujeme, aby byla instance zaregistrovaná pomocí výchozího vyhledávacího názvu, AZURE_KEY_VAULT, který je možné získat rozhraním API SQLServerColumnEncryptionAzureKeyVaultProvider.getName()
. Výchozí název umožňuje používat nástroje, jako je SQL Server Management Studio nebo PowerShell, ke zřizování a správě klíčů Always Encrypted (nástroje používají výchozí název k vygenerování objektu metadat pro hlavní klíč sloupce). Následující příklad ukazuje registraci poskytovatele služby Azure Key Vault. Další informace o metodě SQLServerConnection.registerColumnEncryptionKeyStoreProviders()
naleznete v referenčních informacích k rozhraní API Always Encrypted pro JDBC ovladač.
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Důležitý
Pokud používáte zprostředkovatele úložiště klíčů služby Azure Key Vault, implementace ovladače JDBC ve službě Azure Key Vault má závislosti na těchto knihovnách (z GitHubu), které musí být součástí vaší aplikace:
knihovny microsoft-authentication-library-for-java
Příklad zahrnutí těchto závislostí do projektu Maven najdete v tématu Stažení závislostí MSAL4J a AKV pomocí Apache Mavenu.
Použijte ověřování Azure Key Vault s řízenými identitami
Od ovladače JDBC 8.4.1byla přidána podpora ověřování ve službě Azure Key Vault pomocí spravovaných identit.
Pokud je aplikace hostovaná v Azure, můžete použít spravované identity pro autentizaci do Azure Key Vault. Tím se eliminuje nutnost zadat a zveřejnit všechny přihlašovací údaje v kódu.
Vlastnosti připojení pro ověřování ve službě Key Vault se spravovanými identitami
Pro ovladač JDBC 8.4.1 a novější zavedl ovladač následující vlastnosti připojení:
ConnectionProperty | Možné párování hodnot 1 | Možné párování hodnot 2 | Možné párování hodnot 3 |
---|---|---|---|
autentizace úložiště klíčů | KeyVaultClientSecret | KeyVaultManagedIdentity | Heslo pro úložiště klíčů Java |
úložiště klíčů PrincipalId | <ID klienta aplikace Microsoft Entra> | <ID objektu aplikace Microsoft Entra> (volitelné) | není k dispozici |
keyStoreSecret | <tajný kód klienta aplikace Microsoft Entra> | není k dispozici | <tajný kód nebo heslo pro> úložiště klíčů Java |
Následující příklady ukazují, jak se vlastnosti připojení používají v připojovacím řetězci.
Použití spravované identity k ověření ve službě AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;"
Použijte spravovanou identitu a ID principálu k ověření ve službě AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;keyStorePrincipal=<principalId>"
Ověřování pro AKV pomocí clientId a clientSecret
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultClientSecret;keyStorePrincipalId=<clientId>;keyStoreSecret=<clientSecret>"
Uživatelům se doporučuje použít tyto vlastnosti připojení k určení typu ověřování použitého pro úložiště klíčů místo rozhraní API SQLServerColumnEncryptionAzureKeyVaultProvider
.
Dříve přidané vlastnosti připojení keyVaultProviderClientId
a keyVaultProviderClientKey
jsou zastaralé a nahrazeny vlastnostmi připojení popsanými výše.
Informace o konfiguraci spravovaných identit najdete v tématu Konfigurace spravovaných identit pro prostředky Azure na virtuálním počítači pomocí webu Azure Portal.
Použití zprostředkovatele Windows Certificate Store
SQLServerColumnEncryptionCertificateStoreProvider
lze použít k ukládání hlavních klíčů sloupců v úložišti certifikátů systému Windows. K vytvoření hlavního klíče sloupce a definic šifrovacího klíče sloupce v databázi použijte průvodce Always Encrypted (SSMS) SQL Server Management Studio (SSMS) nebo jiné podporované nástroje. Stejný průvodce lze použít k vygenerování certifikátu podepsaného svým držitelem v úložišti certifikátů Systému Windows, který lze použít jako hlavní klíč sloupce pro data Always Encrypted. Další informace o master klíči sloupce a klíči pro šifrování sloupce v syntaxi T-SQL najdete v tématu CREATE COLUMN MASTER KEY a CREATE COLUMN ENCRYPTION KEY.
Název SQLServerColumnEncryptionCertificateStoreProvider
je MSSQL_CERTIFICATE_STORE a může být dotazován rozhraním API getName() objektu zprostředkovatele. Ovladač ho automaticky zaregistruje a dá se beze změny aplikace bez problémů použít.
Pokud jste si vytvořili hlavní klíč sloupce a šifrovací klíč sloupce založené na úložišti certifikátů systému Windows pomocí SQL Server Management Studio, pak skript T-SQL, který je znovu vytvoří, může vypadat podobně jako tento příklad, zahrnující vlastní specifické KEY_PATH a ENCRYPTED_VALUE.
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...
);
Důležitý
Zatímco ostatní poskytovatelé úložiště klíčů v tomto článku jsou k dispozici na všech platformách podporovaných ovladačem, SQLServerColumnEncryptionCertificateStoreProvider
implementace ovladače JDBC je k dispozici pouze v operačních systémech Windows. Je závislý na mssql-jdbc_auth-<version>-<arch>.dll
, který je dostupný v ovladačovém balíčku. Chcete-li použít tohoto poskytovatele, zkopírujte soubor mssql-jdbc_auth-<version>-<arch>.dll
do adresáře v systémové cestě systému Windows v počítači, kde je nainstalován ovladač JDBC. Případně můžete nastavit vlastnost systému java.library.path pro určení adresáře mssql-jdbc_auth-<version>-<arch>.dll
. Pokud používáte 32bitovou verzi Java Virtual Machine (JVM), použijte mssql-jdbc_auth-<version>-x86.dll
soubor ve složce x86, i když je operační systém verze x64. Pokud používáte 64bitový JVM na procesoru x64, použijte soubor mssql-jdbc_auth-<version>-x64.dll
ve složce x64. Pokud například použijete 32bitový JVM a ovladač JDBC je nainstalovaný ve výchozím adresáři, můžete při spuštění aplikace v Javě zadat umístění knihovny DLL s následujícím argumentem virtuálního počítače: -Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86
Použití zprostředkovatele úložiště klíčů Java
Ovladač JDBC se dodává s integrovanou implementací zprostředkovatele úložiště klíčů pro úložiště klíčů Java. Pokud je vlastnost keyStoreAuthentication
uvedena v připojovacím řetězci a je nastavená na JavaKeyStorePassword
, ovladač automaticky vytvoří instanci a zaregistruje poskytovatele pro Úložiště klíčů Java. Název zprostředkovatele úložiště klíčů Java je MSSQL_JAVA_KEYSTORE. Tento název může být také dotazován pomocí rozhraní API SQLServerColumnEncryptionJavaKeyStoreProvider.getName()
.
Existují tři vlastnosti připojovacího řetězce, které klientské aplikaci umožňují zadat přihlašovací údaje, které ovladač potřebuje k ověření ve službě Java Key Store. Ovladač inicializuje zprostředkovatele na základě hodnot těchto tří vlastností v připojovacím řetězci.
keyStoreAuthentication
: Identifikuje úložiště klíčů Java, které se má použít. S ovladačem Microsoft JDBC 6.0 a novějším pro SQL Server se můžete ověřit v úložišti klíčů Java pouze prostřednictvím této vlastnosti. Pro úložiště klíčů Java musí být hodnota této vlastnosti JavaKeyStorePassword
.
keyStoreLocation
: Cesta k souboru úložiště klíčů Java, který ukládá hlavní klíč sloupce. Cesta obsahuje název souboru úložiště klíčů.
keyStoreSecret
: Tajný klíč/heslo, které se mají použít pro úložiště klíčů a klíč. Pokud chcete použít úložiště klíčů Java, úložiště klíčů a heslo klíče musí být stejné.
Tady je příklad zadání těchto přihlašovacích údajů v připojovacím řetězci:
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>";
Tato nastavení můžete také získat nebo nastavit pomocí objektu SQLServerDataSource
. Další informace naleznete v tématu Always Encrypted API Reference pro ovladač JDBC.
Ovladač JDBC automaticky vytvoří instanci SQLServerColumnEncryptionJavaKeyStoreProvider
, pokud jsou tyto přihlašovací údaje k dispozici ve vlastnostech připojení.
Vytvoření hlavního klíče pro sloupec pro úložiště klíčů Java
SQLServerColumnEncryptionJavaKeyStoreProvider
lze použít s typy úložiště klíčů JKS nebo PKCS12. K vytvoření nebo importu klíče, který se má použít s tímto poskytovatelem, použijte nástroj Java keytool. Klíč musí mít stejné heslo jako samotné úložiště klíčů. Tady je příklad vytvoření veřejného klíče a jeho přidruženého privátního klíče s nástrojem keytool
. Nahraďte <password>
platným heslem.
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.jks -storepass <password> -validity 360 -keysize 2048 -storetype jks
Tento příkaz vytvoří veřejný klíč a zabalí ho do certifikátu podepsaného svým držitelem X.509, který je uložený v úložišti klíčů keystore.jks
spolu s přidruženým privátním klíčem. Tato položka v úložišti klíčů je identifikována aliasem AlwaysEncryptedKey
.
Zde je příklad téhož úložiště typu PKCS12. Nahraďte <password>
platným heslem.
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.pfx -storepass <password> -validity 360 -keysize 2048 -storetype pkcs12 -keypass <password>
Pokud je úložiště klíčů typu PKCS12, nástroj keytool nezobrazí výzvu k zadání hesla klíče a heslo ke klíči musí být k dispozici s možností -keypass
, protože SQLServerColumnEncryptionJavaKeyStoreProvider
vyžaduje, aby úložiště klíčů a klíč měly stejné heslo.
Můžete také exportovat certifikát z úložiště certifikátů systému Windows ve formátu .pfx a použít ho s SQLServerColumnEncryptionJavaKeyStoreProvider
. Exportovaný certifikát lze také importovat do úložiště klíčů Java jako typ úložiště klíčů JKS.
Po vytvoření záznamu keytool vytvořte metadata hlavního klíče sloupce v databázi, k čemuž je potřeba název poskytovatele úložiště klíčů a cesta ke klíči. Další informace o tom, jak vytvořit meta data hlavního klíče sloupce, naleznete v tématu CREATE COLUMN MASTER KEY. Pro SQLServerColumnEncryptionJavaKeyStoreProvider
je cesta ke klíči pouze alias klíče a název SQLServerColumnEncryptionJavaKeyStoreProvider
je MSSQL_JAVA_KEYSTORE
. Tento název můžete také dotazovat pomocí veřejného rozhraní API getName()
třídy SQLServerColumnEncryptionJavaKeyStoreProvider
.
Syntaxe T-SQL pro vytvoření hlavního klíče sloupce je:
CREATE COLUMN MASTER KEY [<CMK_name>]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'<key_alias>'
);
Pro dříve vytvořený klíč AlwaysEncryptedKey by definice hlavního klíče pro sloupec byla:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'AlwaysEncryptedKey'
);
Poznámka
Integrované funkce aplikace SQL Server Management Studio nemůžou vytvářet definice hlavních klíčů sloupců pro úložiště klíčů Java. Příkazy T-SQL se musí používat programově.
Vytvořte šifrovací klíč sloupce pro Java Key Store
SQL Server Management Studio ani žádný jiný nástroj nejde použít k vytvoření šifrovacích klíčů sloupců pomocí hlavních klíčů sloupců v úložišti klíčů Java. Klientská aplikace musí klíč šifrování sloupce vytvořit programově pomocí třídy SQLServerColumnEncryptionJavaKeyStoreProvider
. Další informace najdete v tématu Použití zprostředkovatelů hlavního úložiště klíčů sloupců pro programové zřizování klíčů.
Implementace vlastního poskytovatele úložiště hlavního klíče pro sloupec
Pokud chcete uložit hlavní klíče sloupců v úložišti klíčů, které stávající poskytovatel nepodporuje, můžete implementovat vlastního zprostředkovatele rozšířením třídy SQLServerColumnEncryptionKeyStoreProvider
a registrací poskytovatele jedním z následujících způsobů:
SQLServerConnection.registerColumnEncryptionKeyStoreProviders
-
SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection
(přidáno do JDBC verze 10.2) -
SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement
(přidáno do JDBC verze 10.2)
public class MyCustomKeyStore extends SQLServerColumnEncryptionKeyStoreProvider{
private String name = "MY_CUSTOM_KEYSTORE";
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public byte[] encryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm, byte[] plainTextColumnEncryptionKey)
{
// Logic for encrypting the column encryption key
}
public byte[] decryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm, byte[] encryptedColumnEncryptionKey)
{
// Logic for decrypting the column encryption key
}
}
Zaregistrujte poskytovatele v SQLServerConnection.registerColumnEncryptionKeyStoreProviders
:
SQLServerColumnEncryptionKeyStoreProvider storeProvider = new MyCustomKeyStore();
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(storeProvider.getName(), storeProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Priorita mezipaměti sloupcového šifrovacího klíče
Tato část se týká ovladače JDBC verze 10.2 a vyšší.
Šifrovací klíče sloupce (CEK) dešifrované vlastními poskytovateli úložiště klíčů zaregistrovanými v instanci připojení nebo příkazu nebudou uloženy do mezipaměti ovladačem Microsoft JDBC pro SQL Server. Poskytovatelé vlastních úložišť klíčů by měli implementovat mechanismus ukládání CEK do mezipaměti.
Od verze 10.2 má SQLServerColumnEncryptionAzureKeyVaultProvider
vlastní implementaci mezipaměti CEK. Při registraci na instanci připojení nebo příkazu se sady CEKs dešifrované instancí SQLServerColumnEncryptionAzureKeyVaultProvider
vymažou, když tato instance přejde mimo svůj rozsah:
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
Poznámka
Ukládání do mezipaměti CEK, které je implementováno poskytovateli vlastního úložiště klíčů, bude ovladačem zakázáno, pokud je instance tohoto poskytovatele zaregistrována v ovladači globálně pomocí metody SQLServerConnection.registerColumnEncryptionKeyStoreProviders
. Jakákoli implementace ukládání do mezipaměti CEK by měla nejprve zkontrolovat hodnotu doby trvání životnosti předtím, než uloží klíč CEK do mezipaměti, a neměla by jej uložit do mezipaměti, pokud je tato hodnota nula. Vyhnete se tak duplicitním ukládáním do mezipaměti a možným nejasnostem uživatelů při pokusu o konfiguraci ukládání klíčů do mezipaměti. Hodnotu time-to-live pro mezipaměť lze nastavit pomocí SQLServerColumnEncryptionKeyStoreProvider.setColumnEncryptionCacheTtl
metody.
Registrovat poskytovatele vlastního úložiště hlavního klíče pro sloupec
Tato část se týká ovladače JDBC verze 10.2 a vyšší.
Poskytovatelé vlastních úložišť hlavních klíčů lze zaregistrovat v ovladači ve třech různých vrstvách. Priorita těchto tří registrací je následující:
- Registrace pro jednotlivé příkazy se kontroluje, jestli není prázdná.
- Pokud je registrace pro jednotlivé příkazy prázdná, zkontroluje se registrace připojení, pokud není prázdná.
- Pokud je registrace podle připojení prázdná, zkontroluje se globální registrace.
Jakmile se jakýkoli poskytovatel úložiště klíčů najde na úrovni registrace, ovladač NEBUDE se vrátit k ostatním registracím a vyhledat poskytovatele. Pokud jsou poskytovatelé zaregistrovaní, ale správný poskytovatel se nenajde na úrovni, vyvolá se výjimka, která obsahuje pouze registrované poskytovatele v registraci, která byla zkontrolována.
Integrovaný poskytovatel úložiště hlavního klíče sloupce, který je k dispozici pro úložiště certifikátů systému Windows, je předregistrovaný. Zprostředkovatele úložiště klíčů pro Microsoft Java a úložiště klíčů služby Azure Key Vault lze implicitně zaregistrovat pro instanci připojení, pokud jsou přihlašovací údaje dostupné předem.
Tři úrovně registrace podporují různé scénáře při dotazování šifrovaných dat. Příslušnou metodu lze použít k zajištění přístupu uživatele aplikace k datům ve formátu prostého textu. Přístup k nešifrovaným datům nastane jen v případě, že mohou poskytnout požadovaný hlavní klíč sloupce a ověří se proti úložišti klíčů obsahujícímu hlavní klíč sloupce.
Aplikace, které sdílejí instanci SQLServerConnection
mezi více uživateli, mohou chtít použít SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement
. Každý uživatel musí před spuštěním dotazu zaregistrovat zprostředkovatele úložiště klíčů v instanci SQLServerStatement
, aby měl přístup k šifrovanému sloupci. Pokud zprostředkovatel úložiště klíčů má přístup k požadovanému hlavnímu klíči sloupce v úložišti klíčů, který používá dané přihlašovací údaje uživatele, dotaz bude úspěšný.
Aplikace, které vytvoří instanci SQLServerConnection
pro každého uživatele, mohou chtít použít SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection
. Poskytovatelé úložiště klíčů zaregistrovaní touto metodou mohou být připojením použiti pro jakýkoli dotaz přistupující k šifrovaným datům.
Zprostředkovatelé úložiště klíčů zaregistrovaní v SQLServerConnection.registerColumnEncryptionKeyStoreProviders
použijí identitu danou aplikací při ověřování v úložišti klíčů.
Následující příklad ukazuje prioritu zprostředkovatelů úložiště hlavních klíčů vlastních sloupců zaregistrovaných v instanci připojení:
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);
}
Následující příklad ukazuje přednost zprostředkovatelů úložiště hlavních klíčů sloupcových zaregistrovaných u instance příkazu:
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);
}
}
Použití zprostředkovatelů úložiště klíčů hlavního sloupce pro programové zřizování klíčů
Pro přístup k šifrovaným sloupcům ovladač Microsoft JDBC pro SQL Server transparentně vyhledá a volá zprostředkovatele hlavního úložiště klíčů pravého sloupce k dešifrování šifrovacích klíčů sloupců. Běžný kód aplikace obvykle nevolá přímo zprostředkovatele úložiště hlavních klíčů sloupců. Můžete však vytvořit instanci a programově volat poskytovatele, abyste zřídili a spravovali klíče Always Encrypted. Tento krok může být proveden za účelem vygenerování šifrovaného klíče pro šifrování sloupce a dešifrování klíče pro šifrování sloupce, například jako součást rotace hlavního klíče sloupce. Další informace najdete v tématu Přehled správy klíčů pro funkci Always Encrypted.
Pokud používáte vlastního zprostředkovatele úložiště klíčů, může být potřeba implementovat vlastní nástroje pro správu klíčů. Ke správě a zřizování klíčů můžete použít klíče uložené ve službě Windows Certificate Store nebo ve službě Azure Key Vault. Ke správě a zřizování klíčů můžete použít existující nástroje, jako je SQL Server Management Studio nebo PowerShell. Pokud chcete používat klíče uložené v úložišti klíčů Java, musíte klíče zřizovat programově. Následující příklad ukazuje, jak použít třídu SQLServerColumnEncryptionJavaKeyStoreProvider
k šifrování klíče pomocí klíče uloženého v úložišti klíčů Java.
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();
}
}
Povolení funkce Always Encrypted pro dotazy aplikací
Nejjednodušší způsob, jak povolit šifrování parametrů a dešifrování výsledků dotazu šifrovaných sloupců, je nastavení hodnoty klíčového slova připojovacího řetězce columnEncryptionSetting
na Enabled
.
Následující připojovací řetězec je příkladem povolení funkce Always Encrypted v ovladači JDBC:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;user=<user>;encrypt=true;password=<password>;databaseName=<database>;columnEncryptionSetting=Enabled;";
SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);
Následující kód je ekvivalentní příklad použití SQLServerDataSource
objektu:
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();
Funkce Always Encrypted je také možné povolit pro jednotlivé dotazy. Další informace naleznete v tématu Řízení dopadu výkonu funkce Always Encrypted. Povolení funkce Always Encrypted nestačí k úspěšnému šifrování nebo dešifrování. Musíte se také ujistit, že:
- Aplikace má oprávnění k
VIEW ANY COLUMN MASTER KEY DEFINITION
aVIEW ANY COLUMN ENCRYPTION KEY DEFINITION
databázi, která se vyžadují pro přístup k metadatům o klíčích Always Encrypted v databázi. Podrobnosti najdete v tématu Oprávnění v Always Encrypted (databázový stroj). - Aplikace má přístup k hlavnímu klíči sloupce, který chrání šifrovací klíče sloupců, které šifrují dotazované databázové sloupce. Pokud chcete použít zprostředkovatele úložiště klíčů Java, musíte v připojovacím řetězci zadat další přihlašovací údaje. Další informace najdete v tématu Použití poskytovatele úložiště klíčů Java.
Konfigurace způsobu odesílání hodnot java.sql.Time na server
Vlastnost připojení sendTimeAsDatetime
slouží ke konfiguraci způsobu odeslání hodnoty java.sql.Time na server. Pokud je nastavena hodnota false, je časová hodnota odeslána jako typ času SQL Serveru. Pokud je hodnota true, je časová hodnota odeslána jako typ datetime. Pokud je časový sloupec zašifrovaný, vlastnost sendTimeAsDatetime
musí být false, protože zašifrované sloupce nepodporují převod z času na datetime. Všimněte si také, že tato vlastnost je ve výchozím nastavení true, takže pokud chcete použít šifrované časové sloupce, nastavte ji na false. V opačném případě ovladač vyvolá výjimku. Počínaje verzí 6.0 ovladače má třída SQLServerConnection
dvě metody konfigurace hodnoty této vlastnosti programově:
- public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
- public boolean getSendTimeAsDatetime()
Další informace o této vlastnosti naleznete v tématu Konfigurace způsobu odesílání hodnot java.sql.Time na server.
Konfigurace způsobu odesílání řetězcových hodnot na server
Vlastnost připojení sendStringParametersAsUnicode
slouží ke konfiguraci způsobu odesílání řetězcových hodnot na SQL Server. Pokud je nastavena hodnota true, parametry řetězce se posílají na server ve formátu Unicode. Pokud je nastavena hodnota false, parametry řetězce se posílají ve formátu jiného než Unicode, jako je například ASCII nebo MBCS, místo Unicode. Výchozí hodnota této vlastnosti je true. Pokud je zapnutá funkce Always Encrypted a sloupec char
/varchar
/varchar(max)
je zašifrovaný, musí být hodnota sendStringParametersAsUnicode
nastavena na hodnotu false. Pokud je tato vlastnost nastavena na true, ovladač vyvolá výjimku při dešifrování dat z šifrovaného char
/varchar
/varchar(max)
sloupce, který má znaky Unicode. Další informace o této vlastnosti naleznete v tématu Nastavení vlastností připojení.
Důležitý
Pokud je sendStringParametersAsUnicode
nastavená na true
a data unicode se vloží do sloupce char
/varchar
zašifrovaného pomocí funkce Always Encrypted, může dojít ke ztrátě dat bez nahlášení chyby. Ztrátu dat lze zjistit pouze při pokusu o dešifrování dat po přečtení ze serveru. Výsledkem může být chyba jako 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'.
.
Při vkládání šifrovaných dat je důležité použít správné datové typy sloupců a zadat správný datový typ pro parametry. Pokud se očekávají údaje Unicode, použijte sloupce nchar
/nvarchar
a metody setNString()
. Server nemůže provádět implicitní převody dat a má omezenou schopnost detekovat chyby dat, pokud je povolená funkce Always Encrypted.
Načítání a úpravy dat v šifrovaných sloupcích
Po povolení funkce Always Encrypted pro dotazy aplikace můžete pomocí standardních rozhraní API JDBC načíst nebo upravit data v šifrovaných sloupcích databáze. Pokud má vaše aplikace požadovaná oprávnění k databázi a má přístup k hlavnímu klíči sloupce, ovladač zašifruje všechny parametry dotazu, které cílí na šifrované sloupce, a dešifruje data načtená ze šifrovaných sloupců.
Pokud funkce Always Encrypted není povolená, dotazy s parametry, které cílí na šifrované sloupce, selžou. Dotazy můžou stále načítat data ze šifrovaných sloupců, pokud dotaz nemá žádné parametry, které cílí na šifrované sloupce. Ovladač se ale nebude pokoušet dešifrovat žádné hodnoty načtené ze šifrovaných sloupců a aplikace bude přijímat binární šifrovaná data (jako pole bajtů).
Následující tabulka shrnuje chování dotazů v závislosti na tom, jestli je funkce Always Encrypted povolená nebo ne:
Charakteristika dotazu | Funkce Always Encrypted je povolená a aplikace má přístup ke klíčům a metadatům klíčů. | Funkce Always Encrypted je povolená a aplikace nemá přístup ke klíčům ani metadatům klíčů. | Funkce Always Encrypted je zakázaná. |
---|---|---|---|
Dotazy s parametry, které cílí na šifrované sloupce | Hodnoty parametrů jsou transparentně šifrované. | Chyba | Chyba |
Dotazy načítající data ze šifrovaných sloupců bez parametrů, které cílí na šifrované sloupce. | Výsledky z šifrovaných sloupců se transparentně dešifrují. Aplikace přijímá hodnoty prostého textu datových typů JDBC odpovídající typům SQL Serveru nakonfigurovaným pro šifrované sloupce. | Chyba | Výsledky z šifrovaných sloupců se nešifrují. Aplikace přijímá šifrované hodnoty jako bajtová pole (bajt[]). |
Vkládání a načítání příkladů šifrovaných dat
Následující příklady ilustrují načítání a úpravy dat v šifrovaných sloupcích. Příklady předpokládají cílovou tabulku s následujícím schématem a šifrovanými sloupci SSN a BirthDate. Pokud jste nakonfigurovali hlavní klíč sloupce s názvem MyCMK a šifrovací klíč sloupce s názvem MyCEK (jak je popsáno v předchozích částech zprostředkovatelů úložiště klíčů), můžete vytvořit tabulku pomocí tohoto skriptu:
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
Pro každý příklad kódu Java budete muset vložit kód specifický pro úložiště klíčů do umístění, které jste si poznamenali.
Použití zprostředkovatele úložiště klíčů služby Azure Key Vault:
String clientID = "<Azure Application ID>";
String clientKey = "<Azure Application API Key Password>";
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
K použití zprostředkovatele úložiště certifikátů systému Windows:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
Jak používat poskytovatele úložiště klíčů Java Key Store:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=<path to jks or pfx file>;keyStoreSecret=<keystore secret/password>";
Vkládání dat - příklad
Tento příklad vloží řádek do tabulky Pacientů. Všimněte si následujících položek:
- V ukázkovém kódu není nic specifického pro šifrování. Ovladač Microsoft JDBC pro SQL Server automaticky detekuje a šifruje parametry, které cílí na šifrované sloupce. Díky tomuto chování je šifrování pro aplikaci transparentní.
- Hodnoty vložené do databázových sloupců, včetně šifrovaných sloupců, se předávají jako parametry s
SQLServerPreparedStatement
. I když jsou parametry volitelné při odesílání hodnot do nešifrovaných sloupců (i když se důrazně doporučuje, protože pomáhá zabránit injektáži SQL), je vyžadována pro hodnoty, které cílí na šifrované sloupce. Pokud by hodnoty vložené do šifrovaných sloupců byly předány jako literály vložené do příkazu dotazu, dotaz selže, protože ovladač by nemohl určit hodnoty v cílových šifrovaných sloupcích a nezašifroval by hodnoty. V důsledku toho by server odmítl je jako nekompatibilní se šifrovanými sloupci. - Všechny hodnoty vytištěné programem budou ve formátu prostého textu, protože ovladač Microsoft JDBC pro SQL Server transparentně dešifruje data načtená ze šifrovaných sloupců.
- Pokud provádíte vyhledávání s použitím klauzule WHERE, je třeba hodnotu uvedenou v klauzuli WHERE předat jako parametr, aby ji ovladač mohl před odesláním do databáze bezpečně šifrovat. V následujícím příkladu se SSN předá jako parametr, ale příjmení se předá jako hodnota, protože LastName není šifrované.
- Metoda setter použitá pro parametr cílící na sloupec SSN je
setString()
, která se mapuje na datový typchar
/varchar
SQL Serveru. Pokud se pro tento parametr použila metoda setter, byla použitasetNString()
, která se mapuje nanchar
/nvarchar
, dotaz selže, protože Funkce Always Encrypted nepodporuje převody z šifrovanýchnchar
/nvarchar
hodnot na šifrovanéchar
/varchar
hodnoty.
// <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();
}
Příklad načítání dat ve formátu prostého textu
Následující příklad ukazuje filtrování dat na základě šifrovaných hodnot a načtení dat prostého textu ze šifrovaných sloupců. Všimněte si následujících položek:
- Hodnota, která se používá v klauzuli WHERE k filtrování ve sloupci SSN, musí být předána jako parametr, aby ovladač Microsoft JDBC pro SQL Server mohl transparentně šifrovat před odesláním do databáze.
- Všechny hodnoty vytištěné programem budou ve formátu prostého textu, protože ovladač Microsoft JDBC pro SQL Server transparentně dešifruje data načtená ze sloupců SSN a BirthDate.
Poznámka
pokud jsou sloupce šifrované pomocí deterministického šifrování, dotazy na ně můžou provádět porovnání rovnosti. Další informace najdete v tématu deterministické šifrování.
// <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();
}
Příklad načítání šifrovaných dat
Pokud funkce Always Encrypted není povolená, dotaz může stále načítat data ze šifrovaných sloupců, pokud dotaz nemá žádné parametry, které cílí na šifrované sloupce.
Následující příklad ukazuje načtení binárních šifrovaných dat z šifrovaných sloupců. Všimněte si následujících položek:
- Vzhledem k tomu, že funkce Always Encrypted není v připojovacím řetězci povolená, vrátí dotaz šifrované hodnoty SSN a BirthDate jako pole bajtů (program převede hodnoty na řetězce).
- Dotaz, který načítá data ze šifrovaných sloupců se zakázaným funkcí Always Encrypted, může mít parametry, pokud žádný z parametrů cílí na šifrovaný sloupec. Následující dotazy filtrují podle lastName, který není v databázi šifrovaný. Pokud dotaz filtrovaný podle SSN nebo BirthDate selže.
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();
}
Předcházení běžným problémům při dotazování šifrovaných sloupců
Tato část popisuje běžné kategorie chyb při dotazování šifrovaných sloupců z aplikací Java a několik pokynů, jak se jim vyhnout.
Chyby při převodu nepodporovaného datového typu
Funkce Always Encrypted podporuje několik převodů pro šifrované datové typy. Podrobný seznam podporovaných převodů typů najdete v tématu Always Encrypted (databázový stroj). Tady je postup, jak se vyhnout chybám převodu datových typů. Ujistěte se, že:
při předávání hodnot pro parametry, které cílí na šifrované sloupce, použijete správné metody setter. Ujistěte se, že datový typ parametru v SQL Serveru je přesně stejný jako typ cílového sloupce, nebo že je podporován převod datového typu parametru v SQL Serveru na cílový typ sloupce. Metody rozhraní API byly přidány do
SQLServerPreparedStatement
,SQLServerCallableStatement
a třídySQLServerResultSet
pro předávání parametrů odpovídajících konkrétním datovým typům SQL Serveru. Úplný seznam nových rozhraní API viz Referenční informace k rozhraní API Always Encrypted pro ovladač JDBC. Nedodržování definic datových typů pravděpodobně způsobí chyby kolidování typu operandu. Tady je několik příkladů úprav, které můžou být potřeba při použití funkce Always Encrypted:- Metodu
setTimestamp()
můžete použít k předání parametru do nešifrovaného sloupce datetime2 nebo datetime. Pokud je ale sloupec zašifrovaný, musíte použít přesnou metodu představující typ sloupce v databázi. PomocísetTimestamp()
předejte hodnoty do šifrovaného sloupce datetime2 a pomocísetDateTime()
předávat hodnoty do šifrovaného sloupce datetime. - Metodu
setBinary()
můžete použít k předání parametru nešifrovanémuvarbinary(max)
nebobinary
sloupci. Ovladač ve výchozím nastavení nastaví datový typBINARY
pro parametrysetBinary()
a server může implicitně převést data tak, aby se vkládaly do sloupcevarbinary(max)
. Pokud je ale sloupecvarbinary(max)
zašifrovaný, musíte zadat přesnější typ dat parametrů. Příklad:preparedStatement.setObject(1, binaryData, java.sql.JDBCType.LONGVARBINARY)
- Metodu
přesnost a měřítko parametrů, které cílí na sloupce desetinných a číselných datových typů SQL Serveru, je stejné jako přesnost a měřítko nakonfigurované pro cílový sloupec. Metody rozhraní API byly přidány do tříd
SQLServerPreparedStatement
,SQLServerCallableStatement
aSQLServerResultSet
pro příjem přesnosti a škálování spolu s datovými hodnotami pro parametry/sloupce představující desetinné a číselné datové typy. Úplný seznam nových nebo přetížených rozhraní API najdete v tématu Reference k rozhraním API služby Always Encrypted pro ovladače JDBC.- Pokud například používáte
BigDecimal
Javy jako typ parametru, který cílí na zadaný desetinný sloupec v databázi, musíte zadat přesnost a škálování na metodusetBigDecimal()
nebo metodusetValue()
. Pokud nezadáte správnou přesnost a měřítko, může dojít k chybě, která vypadá takto:
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')
- Pokud například používáte
Přesnost/měřítko desetinných sekund parametrů zaměřených na sloupce
datetime2
,datetimeoffset
nebo na datové typy času SQL Serveru není větší než přesnost/měřítko desetinných sekund cílového sloupce v dotazech, které upravují hodnoty cílového sloupce. Metody rozhraní API byly přidány do třídSQLServerPreparedStatement
,SQLServerCallableStatement
aSQLServerResultSet
pro příjem přesnosti a škálování desetinné sekundy spolu s datovými hodnotami pro parametry představující tyto datové typy. Úplný seznam nových/přetížených rozhraní API najdete v tématu Referenční informace k rozhraní API Always Encrypted pro ovladač JDBC.
Chyby způsobené nesprávnými vlastnostmi připojení
Tato část popisuje, jak správně nakonfigurovat nastavení připojení tak, aby používala data Always Encrypted. Vzhledem k tomu, že šifrované datové typy podporují omezené převody, sendTimeAsDatetime
a sendStringParametersAsUnicode
nastavení připojení potřebují správnou konfiguraci pro použití šifrovaných sloupců. Ujistěte se, že:
- nastavení připojení sendTimeAsDatetime je při vkládání dat do šifrovaných časových sloupců nastaveno na false. Další informace najdete v tématu Konfigurace způsobu odesílání hodnot java.sql.Time na server.
- sendStringParametersAsUnicode nastavení připojení je při vkládání dat do šifrovaných sloupců char/varchar/varchar(max) nastaveno na true (nebo je ponecháno jako výchozí).
Chyby způsobené předáváním prostého textu místo šifrovaných hodnot
Všechny hodnoty, které cílí na šifrovaný sloupec, musí být v aplikaci zašifrované. Při pokusu o vložení nebo úpravu nebo filtrování podle hodnoty prostého textu v zašifrovaném sloupci dojde k chybě podobné této:
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'
Pokud chcete těmto chybám zabránit, ujistěte se, že:
- Funkce Always Encrypted je povolená pro dotazy aplikací, které cílí na šifrované sloupce (pro připojovací řetězec nebo pro konkrétní dotaz).
- použijete připravené příkazy a parametry k odesílání dat určených pro šifrované sloupce. Následující příklad ukazuje dotaz, který nesprávně filtruje literálem nebo konstantou v šifrovaném sloupci (SSN) místo předání literálu jako parametru. Tento dotaz selže:
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM Customers WHERE SSN='795-73-9838'");
Vynucení šifrování vstupních parametrů
Funkce Vynucení šifrování zajišťuje šifrování parametru pomocí Always Encrypted. Pokud se použije vynucené šifrování a SQL Server informuje ovladač, že parametr nemusí být šifrovaný, dotaz, který tento parametr používá, selže. Tato vlastnost poskytuje přidanou ochranu před útoky na zabezpečení, které zahrnují ohrožený SQL Server poskytující klientovi nesprávná metadata šifrování, což může vést k vyzrazení dat. Metody set* ve třídách SQLServerPreparedStatement
a SQLServerCallableStatement
a metod update*
ve třídě SQLServerResultSet
jsou přetíženy tak, aby přijímaly logický argument k určení nastavení vynucení šifrování. Pokud je hodnota tohoto argumentu false, ovladač nevynutí šifrování parametrů. Pokud je vynucené šifrování nastaveno na hodnotu true, odešle se parametr dotazu pouze v případě, že je cílový sloupec šifrovaný a funkce Always Encrypted je povolená pro připojení nebo příkaz. Tato vlastnost poskytuje další vrstvu zabezpečení, která zajišťuje, aby ovladač omylem neodesílal data do SQL Serveru jako prostý text, když se očekává, že se šifrují.
Další informace o metodách SQLServerPreparedStatement
a SQLServerCallableStatement
, které jsou přetížené nastavením vynuceného šifrování, najdete v tématu Referenční informace k rozhraní API always Encrypted pro ovladač JDBC
Řízení dopadu na výkon funkce Always Encrypted
Vzhledem k tomu, že funkce Always Encrypted je technologie šifrování na straně klienta, většina režijních nákladů na výkon se pozoruje na straně klienta, ne v databázi. Kromě nákladů na operace šifrování a dešifrování jsou další zdroje režijních nákladů na výkon na straně klienta:
- Přidány zpětné dotazy do databáze pro načtení metadat pro parametry dotazu.
- Volání do úložiště hlavního klíče sloupce za účelem přístupu k hlavnímu klíči sloupce.
Tato část popisuje integrované optimalizace výkonu v ovladači Microsoft JDBC pro SQL Server a o tom, jak můžete řídit dopad dříve uvedených dvou faktorů na výkon.
Řízení obousměrných cest za účelem načtení metadat pro parametry dotazu
Pokud je pro připojení povoleno funkce Always Encrypted, ovladač ve výchozím nastavení zavolá sys.sp_describe_parameter_encryption pro každý parametrizovaný dotaz a předá do databáze příkaz dotazu (bez hodnot parametrů). sys.sp_describe_parameter_encryption analyzuje příkaz dotazu, aby zjistil, jestli některé parametry musí být šifrované, a pokud ano, vrátí informace související s šifrováním, které ovladači umožňují zašifrovat hodnoty parametrů. Toto chování zajišťuje vysokou úroveň transparentnosti pro klientskou aplikaci. Pokud aplikace používá parametry k předávání hodnot, které cílí na šifrované sloupce ovladače, aplikace (a vývojář aplikace) nemusí vědět, které dotazy přistupují k šifrovaným sloupcům.
Nastavení funkce Always Encrypted na úrovni dotazu
Pokud chcete řídit dopad na výkon načítání metadat šifrování pro parametrizované dotazy, můžete povolit funkci Always Encrypted pro jednotlivé dotazy místo nastavení pro připojení. Tímto způsobem můžete zajistit, aby se sys.sp_describe_parameter_encryption volala jenom pro dotazy, které víte, že mají parametry cílené na šifrované sloupce. Mějte ale na paměti, že tím snížíte transparentnost šifrování: pokud změníte vlastnosti šifrování sloupců databáze, budete možná muset změnit kód aplikace, aby byl v souladu se změnami schématu.
Pokud chcete řídit chování Always Encrypted jednotlivých dotazů, musíte nakonfigurovat jednotlivé objekty příkazů pomocí výčtu SQLServerStatementColumnEncryptionSetting, který určuje, jak se budou data odesílat a přijímat při čtení a zápisu šifrovaných sloupců pro tento konkrétní příkaz. Tady je několik užitečných pokynů:
Pokud většina dotazů, které klientská aplikace odesílá přes připojení k databázi, přistupuje k šifrovaným sloupcům, použijte tyto pokyny:
- Nastavte klíčové slovo připojovacího řetězce
columnEncryptionSetting
naEnabled
. - Nastavte
SQLServerStatementColumnEncryptionSetting.Disabled
pro jednotlivé dotazy, které nemají přístup k žádným šifrovaným sloupcům. Toto nastavení zakáže jak volánísys.sp_describe_parameter_encryption
, tak dešifrování všech hodnot v sadě výsledků. - Nastavte
SQLServerStatementColumnEncryptionSetting.ResultSet
pro jednotlivé dotazy, které neobsahují žádné parametry vyžadující šifrování, ale načítají data z šifrovaných sloupců. Toto nastavení zakáže volánísys.sp_describe_parameter_encryption
a šifrování parametrů. Dotaz dešifruje výsledky ze sloupců šifrování.
- Nastavte klíčové slovo připojovacího řetězce
Pokud většina dotazů, které klientská aplikace odesílá přes připojení k databázi, nemá přístup k šifrovaným sloupcům, postupujte podle těchto pokynů:
- Nastavte klíčové slovo připojovacího řetězce
columnEncryptionSetting
naDisabled
. - Nastavte
SQLServerStatementColumnEncryptionSetting.Enabled
pro jednotlivé dotazy, které mají všechny parametry, které je potřeba zašifrovat. Toto nastavení umožní jak volánísys.sp_describe_parameter_encryption
, tak dešifrování všech výsledků dotazu načtených ze šifrovaných sloupců. - Nastavte
SQLServerStatementColumnEncryptionSetting.ResultSet
pro dotazy, které neobsahují žádné parametry vyžadující šifrování, ale načítají data ze šifrovaných sloupců. Toto nastavení zakáže volánísys.sp_describe_parameter_encryption
a šifrování parametrů. Dotaz dešifruje výsledky ze sloupců šifrování.
- Nastavte klíčové slovo připojovacího řetězce
Nastavení SQLServerStatementColumnEncryptionSetting
se nedá použít k obejití šifrování a získání přístupu k datům ve formátu prostého textu. Další informace o konfiguraci šifrování sloupců pro příkaz naleznete v tématu Referenční informace k rozhraní API always Encrypted pro ovladač JDBC.
V následujícím příkladu je funkce Always Encrypted pro připojení k databázi zakázaná. Dotaz, který aplikace vydává, má parametr, který cílí na sloupec LastName, který není šifrovaný. Dotaz načte data ze sloupců SSN i BirthDate, které jsou šifrované. V takovém případě není vyžadováno volání sys.sp_describe_parameter_encryption
pro načtení metadat šifrování. Dešifrování výsledků dotazu je však potřeba povolit, aby aplikace mohl přijímat hodnoty prostého textu ze dvou šifrovaných sloupců. K zajištění toho se používá nastavení SQLServerStatementColumnEncryptionSetting.ResultSet
.
// 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();
}
Ukládání metadat parametrů dotazu do mezipaměti
Aby se snížil počet dotazů na databázi, může ovladač Microsoft JDBC pro SQL Server ukládat do mezipaměti informace související se šifrováním pro parametry dotazu. Od verze 11.2.0 budou informace týkající se šifrování parametrů, které vrací volání sys.sp_describe_parameter_encryption, uloženy ovladačem do mezipaměti, pokud přidružený proces SQL Serveru nevyužívá zabezpečené enklávy. Pro ukládání do mezipaměti s využitím zabezpečených enkláv musí server podporovat opětovné vytvoření relace enklávy v případech, kdy už relace není platná.
Ukládání šifrovacích klíčů sloupců do mezipaměti
Aby se snížil počet volání do úložiště hlavních klíčů sloupce pro dešifrování šifrovacích klíčů sloupců, uloží ovladač Microsoft JDBC pro SQL Server šifrovací klíče ve sloupci prostého textu do paměti. Jakmile ovladač obdrží hodnotu šifrovaného klíčového sloupce z metadat databáze, nejprve se pokusí najít odpovídající prostý šifrovací klíč sloupce. Ovladač volá úložiště klíčů obsahující hlavní klíč sloupce pouze v případě, že v mezipaměti nemůže najít zašifrovanou hodnotu šifrovacího klíče sloupce.
Hodnotu time-to-live můžete nakonfigurovat pro položky šifrovacího klíče sloupce v mezipaměti pomocí rozhraní API, setColumnEncryptionKeyCacheTtl()
, ve třídě SQLServerConnection
. Výchozí hodnota TTL (doba života) pro položky šifrovacího klíče sloupce v mezipaměti je dvě hodiny. Pokud chcete ukládání do mezipaměti vypnout, použijte hodnotu 0. K nastavení hodnoty time-to-live použijte následující rozhraní API:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (int columnEncryptionKeyCacheTTL, TimeUnit unit)
Pokud chcete například nastavit hodnotu doby životnosti na 10 minut, použijte:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (10, TimeUnit.MINUTES)
Jako časovou jednotku se podporují jenom DNY, HODINY, MINUTY nebo SEKUNDY.
Kopírování šifrovaných dat pomocí SQLServerBulkCopy
S SQLServerBulkCopy
můžete kopírovat data, která jsou už zašifrovaná a uložená v jedné tabulce, do jiné tabulky bez dešifrování dat. Uděláte to takto:
- Ujistěte se, že konfigurace šifrování cílové tabulky je stejná jako konfigurace zdrojové tabulky. Konkrétně obě tabulky musí mít zašifrované stejné sloupce a sloupce musí být šifrované pomocí stejných typů šifrování a stejných šifrovacích klíčů. Pokud je některý cílový sloupec zašifrovaný jinak než odpovídající zdrojový sloupec, nebudete po operaci kopírování moct dešifrovat data v cílové tabulce. Data budou poškozena.
- Nakonfigurujte připojení databáze ke zdrojové tabulce i cílové tabulce bez povolené funkce Always Encrypted.
- Nastavte možnost
allowEncryptedValueModifications
. Další informace naleznete v tématu Použití hromadného kopírování s ovladačem JDBC.
Poznámka
Při zadávání AllowEncryptedValueModifications
buďte opatrní, protože tato možnost může vést k poškození databáze, protože ovladač Microsoft JDBC pro SQL Server nekontroluje, jestli jsou data skutečně šifrovaná nebo jestli jsou správně zašifrovaná se stejným typem šifrování, algoritmem a klíčem jako cílový sloupec.