Always Encrypted gebruiken met het JDBC-stuurprogramma
JDBC-stuurprogramma downloaden
Op deze pagina vindt u informatie over het ontwikkelen van Java-toepassingen voor het gebruik van Always Encrypted- met het Microsoft JDBC-stuurprogramma 6.0 (of hoger) voor SQL Server.
Met Always Encrypted kunnen clients gevoelige gegevens versleutelen en nooit de gegevens of de versleutelingssleutels onthullen aan SQL Server of Azure SQL Database. Een always encrypted-stuurprogramma, zoals het Microsoft JDBC-stuurprogramma 6.0 (of hoger) voor SQL Server, bereikt dit gedrag door gevoelige gegevens in de clienttoepassing transparant te versleutelen en ontsleutelen. Het stuurprogramma bepaalt welke queryparameters overeenkomen met Always Encrypted-databasekolommen en versleutelt de waarden van deze parameters voordat deze naar de database worden verzonden. Op dezelfde manier decodeert het stuurprogramma gegevens die zijn opgehaald uit versleutelde databasekolommen in de resultaten van queries. Zie Always Encrypted (Database Engine) en Always Encrypted-API-verwijzing voor het JDBC-stuurprogrammavoor meer informatie.
Voorwaarden
- Zorg ervoor dat Microsoft JDBC-stuurprogramma 6.0 (of hoger) voor SQL Server is geïnstalleerd op uw ontwikkelcomputer.
- Download en installeer de Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Lees het Readme-bestand in het zip-bestand voor installatie-instructies, en relevante details over mogelijke export- of importproblemen.
- Voor mssql-jdbc-X.X.X.jre7.jar of sqljdbc41.jar kunnen de policy-bestanden worden gedownload van Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download
- Voor mssql-jdbc-X.X.X.jre8.jar of sqljdbc42.jar kunnen de beleidsbestanden worden gedownload van Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download
- Voor jre-versie 9 of hoger (bijvoorbeeld mssql-jdbc-X.X.X.jre9.jar), hoeft er geen beleidsbestand te worden gedownload. Het jurisdictiebeleid in Java 9 en hoger wordt standaard ingesteld op onbeperkte sterkteversleuteling.
Werken met hoofdsleutelarchieven voor kolommen
Voor het versleutelen of ontsleutelen van gegevens voor versleutelde kolommen onderhoudt SQL Server kolomversleutelingssleutels. Kolomversleutelingssleutels worden opgeslagen in versleutelde vorm in de metagegevens van de database. Elke kolomversleutelingssleutel heeft een bijbehorende kolomhoofdsleutel die wordt gebruikt voor het versleutelen van de kolomversleutelingssleutel.
De metagegevens van de database bevatten niet de kolomhoofdsleutels. Deze sleutels worden alleen bewaard door de client. De metagegevens van de database bevatten echter wel informatie over waar de kolomhoofdsleutels worden opgeslagen ten opzichte van de client. De metagegevens van de database kunnen bijvoorbeeld zeggen dat het sleutelarchief met een kolomhoofdsleutel het Windows-certificaatarchief is en het specifieke certificaat dat wordt gebruikt voor het versleutelen en ontsleutelen, bevindt zich op een specifiek pad in het Windows-certificaatarchief.
Als de client toegang heeft tot dat certificaat in het Windows-certificaatarchief, kan het certificaat worden verkregen. Het certificaat kan vervolgens worden gebruikt om de kolomversleutelingssleutel te ontsleutelen. Vervolgens kan die versleutelingssleutel worden gebruikt om gegevens te ontsleutelen of te versleutelen voor versleutelde kolommen die gebruikmaken van die kolomversleutelingssleutel.
Het Microsoft JDBC-stuurprogramma voor SQL Server communiceert met een sleutelarchief dat een kolomhoofdsleutelarchiefprovider gebruikt, wat een exemplaar is van een klasse die is afgeleid van SQLServerColumnEncryptionKeyStoreProvider
.
Ingebouwde providers voor hoofdsleutelarchief voor kolommen gebruiken
Het Microsoft JDBC-stuurprogramma voor SQL Server wordt geleverd met de volgende ingebouwde hoofdsleutelopslagproviders voor kolommen. Sommige van deze providers zijn preregistreerd met de naam van de specifieke provider (gebruikt om de provider op te zoeken) en sommige vereisen extra inloggegevens of expliciete registratie.
Klas | Beschrijving | Providernaam (opzoeknaam) | Is vooraf geregistreerd? | Perron |
---|---|---|---|---|
SQLServerColumnEncryptionAzureKeyVaultProvider |
Een provider voor een sleutelarchief voor Azure Key Vault. | AZURE_KEY_VAULT | Geen vóór JDBC-stuurprogrammaversie 7.4.1, maar ja vanaf JDBC-stuurprogrammaversie 7.4.1. | Windows, Linux, macOS |
SQLServerColumnEncryptionCertificateStoreProvider |
Een provider van de Windows-certificatenopslag. | MSSQL_CERTIFICATE_STORE | Ja | Ramen |
SQLServerColumnEncryptionJavaKeyStoreProvider |
Een provider voor het Java-sleutelarchief. | MSSQL_JAVA_KEYSTORE | Ja | Windows, Linux, macOS |
Voor de vooraf geregistreerde sleutelarchiefproviders hebt u geen wijzigingen in de toepassingscode nodig om deze providers te gebruiken, maar let op de volgende items:
- U moet ervoor zorgen dat de providernaam die is geconfigureerd in de metagegevens van de kolomhoofdsleutel juist is en dat het pad naar de hoofdsleutel van de kolom de indeling van het sleutelpad volgt die geldig is voor een bepaalde provider. Het is raadzaam om de sleutels te configureren met hulpprogramma's zoals SQL Server Management Studio, waarmee automatisch de geldige providernamen en sleutelpaden worden gegenereerd om de instructie
CREATE COLUMN MASTER KEY
(Transact-SQL) uit te geven. - Zorg ervoor dat uw toepassing toegang heeft tot de sleutel in het sleutelarchief. Deze taak kan inhouden dat uw applicatie toegang krijgt tot de sleutel en/of de sleutelhanger. Afhankelijk van het sleutelarchief kunnen dit configuratiestappen omvatten die specifiek zijn voor het sleutelarchief. Als u bijvoorbeeld de
SQLServerColumnEncryptionJavaKeyStoreProvider
wilt gebruiken, moet u de locatie en het wachtwoord van het sleutelarchief opgeven in de verbindingseigenschappen.
Al deze keystore-providers worden gedetailleerder beschreven in de volgende secties. U hoeft slechts één keystore-provider te implementeren om Always Encrypted te gebruiken.
Azure Key Vault-provider gebruiken
Azure Key Vault is een handige optie voor het opslaan en beheren van kolomhoofdsleutels voor Always Encrypted (met name als uw toepassing wordt gehost in Azure). Het Microsoft JDBC-stuurprogramma voor SQL Server bevat een ingebouwde provider, SQLServerColumnEncryptionAzureKeyVaultProvider
, voor toepassingen met sleutels die zijn opgeslagen in Azure Key Vault. De naam van deze provider is AZURE_KEY_VAULT.
Notitie
De Azure Key Vault-provider die is ingebouwd in het JDBC-stuurprogramma ondersteunt zowel Kluizen als beheerde HSM's in Azure Key Vault.
Als u de Azure Key Vault-opslagprovider wilt gebruiken, moet een toepassingsontwikkelaar de kluis en de sleutels in Azure Key Vault maken en een app-registratie maken in Microsoft Entra ID (voorheen Azure Active Directory). De geregistreerde toepassing moet de machtigingen Get, Decrypt, Encrypt, Unwrap Key, Wrap Key en Verify krijgen in het toegangsbeleid dat is gedefinieerd voor de sleutelkluis die is gemaakt voor gebruik met Always Encrypted. Raadpleeg Azure Key Vault: stapsgewijze handleiding en Kolomhoofdsleutels maken in Azure Key Vaultvoor meer informatie over het instellen van de sleutelkluis en het maken van een kolomhoofdsleutel.
Voor de Azure Key Vault-provider valideert het JDBC-stuurprogramma het pad naar de kolomhoofdsleutel op basis van de lijst met vertrouwde eindpunten. Vanaf versie 8.2.2 kan deze lijst worden geconfigureerd: maak een mssql-jdbc.properties
bestand in de werkmap van de toepassing, stel de eigenschap AKVTrustedEndpoints
in op een door puntkomma's gescheiden lijst. Als de waarde begint met een puntkomma, wordt de standaardlijst uitgebreid. Anders wordt de standaardlijst vervangen.
De standaard vertrouwde eindpunten zijn:
*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+)
Als u voor de voorbeelden op deze pagina een op Azure Key Vault gebaseerde kolomhoofdsleutel en kolomversleutelingssleutel hebt gemaakt met SQL Server Management Studio, kan het T-SQL-script om deze opnieuw te maken er ongeveer uitzien als in dit voorbeeld met een eigen specifieke KEY_PATH en 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...
);
Een toepassing die gebruikmaakt van het JDBC-stuurprogramma kan azure Key Vault gebruiken. De syntaxis of instructies voor dit gebruik van Azure Key Vault zijn gewijzigd vanaf JDBC-stuurprogrammaversie 7.4.1.
JDBC-stuurprogramma 7.4.1 of hoger
Deze sectie omvat JDBC-stuurprogrammaversie 7.4.1 of hoger.
Een clienttoepassing die gebruikmaakt van het JDBC-stuurprogramma kan configureren voor het gebruik van Azure Key Vault door keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>
te vermelden in de JDBC-verbindingsreeks.
Hier volgt een voorbeeld van deze configuratiegegevens in een JDBC-verbindingsreeks.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>";
Het JDBC-stuurprogramma instantieert automatisch een SQLServerColumnEncryptionAzureKeyVaultProvider
-object wanneer deze referenties aanwezig zijn in de verbindingseigenschappen.
Belangrijk
De verbindingseigenschappen keyVaultProviderClientId
en keyVaultProviderClientKey
zijn afgeschaft vanaf v8.4.1. Gebruikers worden aangemoedigd om in plaats daarvan keyStoreAuthentication
, KeyStorePrincipalId
en KeyStoreSecret
te gebruiken.
JDBC-stuurprogrammaversies vóór 7.4.1
Deze sectie omvat JDBC-stuurprogrammaversies vóór 7.4.1.
Een clienttoepassing die gebruikmaakt van het JDBC-stuurprogramma, moet een SQLServerColumnEncryptionAzureKeyVaultProvider
-object instantiëren en het object vervolgens registreren bij het stuurprogramma.
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
clientID
is de toepassings-id van een app-registratie in een Microsoft Entra-tenant.
clientKey
is een sleutelwachtwoord dat is geregistreerd bij die toepassing, die API-toegang biedt tot de Azure Key Vault.
Nadat de toepassing een exemplaar van SQLServerColumnEncryptionAzureKeyVaultProvider
heeft gemaakt, moet de toepassing het exemplaar registreren bij het stuurprogramma met de methode SQLServerConnection.registerColumnEncryptionKeyStoreProviders()
. Het wordt ten zeerste aanbevolen dat het exemplaar is geregistreerd met behulp van de standaard opzoeknaam, AZURE_KEY_VAULT, die kan worden verkregen door de SQLServerColumnEncryptionAzureKeyVaultProvider.getName()
-API. Met de standaardnaam kunt u hulpprogramma's zoals SQL Server Management Studio of PowerShell gebruiken om Always Encrypted-sleutels in te richten en te beheren (de hulpprogramma's gebruiken de standaardnaam om het metagegevensobject te genereren naar de hoofdsleutel van de kolom). In het volgende voorbeeld ziet u hoe u de Azure Key Vault-provider registreert. Zie Always Encrypted-API-verwijzing voor het JDBC-stuurprogrammavoor meer informatie over de methode SQLServerConnection.registerColumnEncryptionKeyStoreProviders()
.
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Belangrijk
Als u de Azure Key Vault-sleutelarchiefprovider gebruikt, heeft de Azure Key Vault-implementatie van het JDBC-stuurprogramma afhankelijkheden van deze bibliotheken (van GitHub) die moeten worden opgenomen in uw toepassing:
Microsoft-authenticatiebibliotheek-voor-Java
Zie MSAL4J- en AKV-afhankelijkheden downloaden met Apache Maven- voor een voorbeeld van het opnemen van deze afhankelijkheden in een Maven-project
Azure Key Vault-verificatie gebruiken met beheerde identiteiten
Vanaf het JDBC-stuurprogramma 8.4.1heeft het stuurprogramma ondersteuning toegevoegd voor verificatie bij Azure Key Vaults met beheerde identiteiten.
U kunt beheerde identiteiten gebruiken om te verifiëren bij Azure Key Vault als de toepassing wordt gehost in Azure. Hierdoor hoeft u geen authenticatiegegevens op te geven of bloot te stellen in de code.
Verbindingseigenschappen voor Key Vault-verificatie met beheerde identiteiten
Voor JDBC-stuurprogramma 8.4.1 en hoger heeft het stuurprogramma de volgende verbindingseigenschappen geïntroduceerd:
Verbindingseigenschap | Mogelijke waardekoppeling 1 | Mogelijke waardekoppeling 2 | Mogelijke waardekoppeling 3 |
---|---|---|---|
keyStore-authenticatie | KeyVaultClientSecret | KeyVaultManagedIdentity | JavaKeyStorePassword |
keyStorePrincipalId | <Client-id van Microsoft Entra Application> | <Microsoft Entra applicatieobject-ID> (optioneel) | n.v.t |
keyStoreSecret | <Clientgeheim van Microsoft Entra Application> | n.v.t | <geheim/wachtwoord voor de Java Key Store> |
In de volgende voorbeelden ziet u hoe de verbindingseigenschappen worden gebruikt in een verbindingsreeks.
Beheerde identiteit gebruiken om te verifiëren bij AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;"
Beheerde identiteit en de principal-id gebruiken om te authenticeren bij AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;keyStorePrincipal=<principalId>"
ClientId en clientSecret gebruiken voor verificatie bij AKV
"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultClientSecret;keyStorePrincipalId=<clientId>;keyStoreSecret=<clientSecret>"
Gebruikers worden aangeraden deze verbindingseigenschappen te gebruiken om het type verificatie op te geven dat wordt gebruikt voor de sleutelarchieven in plaats van de SQLServerColumnEncryptionAzureKeyVaultProvider
-API.
Eerder toegevoegde verbindingseigenschappen keyVaultProviderClientId
en keyVaultProviderClientKey
worden afgeschaft en vervangen door de eerder beschreven verbindingseigenschappen.
Zie Beheerde identiteiten configureren voor Azure-resources op een VIRTUELE machine met behulp van azure Portalvoor meer informatie over het configureren van beheerde identiteiten.
Windows Certificate Store-provider gebruiken
De SQLServerColumnEncryptionCertificateStoreProvider
kan worden gebruikt voor het opslaan van kolomhoofdsleutels in het Windows-certificaatarchief. Gebruik de wizard SQL Server Management Studio (SSMS) Always Encrypted of andere ondersteunde hulpprogramma's om de definities van de kolomhoofdsleutel en kolomversleutelingssleutel in de database te maken. Dezelfde wizard kan worden gebruikt om een zelfondertekend certificaat te genereren in het Windows-certificaatarchief dat kan worden gebruikt als een kolomhoofdsleutel voor de Always Encrypted-gegevens. Zie CREATE COLUMN MASTER KEY en CREATE COLUMN ENCRYPTION KEY voor meer informatie over de T-SQL-syntaxis voor kolomhoofdsleutel en kolomversleutelingssleutel.
De naam van de SQLServerColumnEncryptionCertificateStoreProvider
is MSSQL_CERTIFICATE_STORE en kan worden opgevraagd door de getName() API van het providerobject. Het wordt automatisch geregistreerd door het stuurprogramma en kan naadloos worden gebruikt zonder dat er wijzigingen in de toepassing zijn.
Als u voor de voorbeelden op deze pagina een op Windows Certificate Store gebaseerde kolomhoofdsleutel en kolomversleutelingssleutel hebt gemaakt met SQL Server Management Studio, kan het T-SQL-script om deze opnieuw te maken er ongeveer als volgt uitzien als in dit voorbeeld met een eigen specifieke KEY_PATH en 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...
);
Belangrijk
Hoewel de andere sleutelarchiefproviders in dit artikel beschikbaar zijn op alle platforms die door het stuurprogramma worden ondersteund, is de SQLServerColumnEncryptionCertificateStoreProvider
implementatie van het JDBC-stuurprogramma alleen beschikbaar op Windows-besturingssystemen. Het heeft een afhankelijkheid van mssql-jdbc_auth-<version>-<arch>.dll
die beschikbaar is binnen het stuurprogrammapakket. Als u deze provider wilt gebruiken, kopieert u het mssql-jdbc_auth-<version>-<arch>.dll
bestand naar een map op het Windows-systeempad op de computer waarop het JDBC-stuurprogramma is geïnstalleerd. U kunt ook de systeemeigenschap java.library.path instellen om de map van de mssql-jdbc_auth-<version>-<arch>.dll
op te geven. Als u een 32-bits Java Virtual Machine (JVM) gebruikt, gebruikt u het mssql-jdbc_auth-<version>-x86.dll
-bestand in de x86-map, zelfs als het besturingssysteem de x64-versie is. Als u een 64-bits JVM uitvoert op een x64-processor, gebruikt u het mssql-jdbc_auth-<version>-x64.dll
-bestand in de x64-map. Als u bijvoorbeeld de 32-bits JVM gebruikt en het JDBC-stuurprogramma is geïnstalleerd in de standaardmap, kunt u de locatie van het DLL-bestand opgeven met het volgende argument voor de virtuele machine (VM) wanneer de Java-toepassing wordt gestart: -Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86
Java Key Store-provider gebruiken
Het JDBC-stuurprogramma wordt geleverd met een ingebouwde implementatie van de keystore-provider voor de Java Key Store. Als de eigenschap keyStoreAuthentication
in de verbindingsreeks aanwezig is en is ingesteld op JavaKeyStorePassword
, wordt de provider automatisch geïnitieerd en geregistreerd voor Java Key Store. De naam van de Java Key Store-provider is MSSQL_JAVA_KEYSTORE. Deze naam kan ook worden opgevraagd door de SQLServerColumnEncryptionJavaKeyStoreProvider.getName()
-API.
Er zijn drie verbindingsreekseigenschappen waarmee een clienttoepassing de referenties kan opgeven die het stuurprogramma nodig heeft om te verifiëren bij de Java Key Store. Het stuurprogramma initialiseert de provider op basis van de waarden van deze drie eigenschappen in de verbindingsreeks.
keyStoreAuthentication
: identificeert de Java-sleutelarchief die gebruikt moet worden. Met Microsoft JDBC-stuurprogramma 6.0 en hoger voor SQL Server kunt u zich alleen verifiëren bij het Java Key Store via deze eigenschap. Voor het Java-sleutelarchief moet de waarde voor deze eigenschap JavaKeyStorePassword
zijn.
keyStoreLocation
: het pad naar het Java Key Store-bestand waarin de kolomhoofdsleutel wordt opgeslagen. Het pad bevat de bestandsnaam van het sleutelarchief.
keyStoreSecret
: het wachtwoord dat moet worden gebruikt voor de keystore en de sleutel. Als u het Java-sleutelarchief wilt gebruiken, moeten het sleutelarchief en het sleutelwachtwoord hetzelfde zijn.
Hier volgt een voorbeeld van het opgeven van deze referenties in de verbindingsreeks:
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>";
U kunt deze instellingen ook ophalen of instellen met het SQLServerDataSource
-object. Zie Always Encrypted-API-verwijzing voor het JDBC-stuurprogrammavoor meer informatie.
Het JDBC-stuurprogramma instantieert automatisch de SQLServerColumnEncryptionJavaKeyStoreProvider
wanneer deze referenties aanwezig zijn in verbindingseigenschappen.
Een kolomhoofdsleutel maken voor het Java-sleutelarchief
De SQLServerColumnEncryptionJavaKeyStoreProvider
kan worden gebruikt met JKS- of PKCS12-sleutelopslagtypen. Als u een sleutel wilt maken of importeren voor gebruik met deze provider, gebruikt u het hulpprogramma Java keytool. De sleutel moet hetzelfde wachtwoord hebben als het sleutelarchief zelf. Hier volgt een voorbeeld van het maken van een openbare sleutel en de bijbehorende persoonlijke sleutel met het hulpprogramma keytool
. Vervang <password>
door een geldig wachtwoord.
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.jks -storepass <password> -validity 360 -keysize 2048 -storetype jks
Met deze opdracht maakt u een openbare sleutel en verpakt deze in een zelfondertekend X.509-certificaat, dat is opgeslagen in het sleutelarchief keystore.jks
samen met de bijbehorende persoonlijke sleutel. Deze vermelding in het sleutelarchief wordt geïdentificeerd door de alias AlwaysEncryptedKey
.
Hier volgt een voorbeeld van hetzelfde met een PKCS12-winkeltype. Vervang <password>
door een geldig wachtwoord.
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.pfx -storepass <password> -validity 360 -keysize 2048 -storetype pkcs12 -keypass <password>
Als het sleutelarchief van het type PKCS12 is, vraagt het hulpprogramma keytool niet om een sleutelwachtwoord en moet het sleutelwachtwoord worden opgegeven met -keypass
optie, omdat de SQLServerColumnEncryptionJavaKeyStoreProvider
vereist dat de sleutelopslag en de sleutel hetzelfde wachtwoord hebben.
U kunt ook een certificaat exporteren uit de Windows-certificaatopslag in .pfx-indeling en dat gebruiken met de SQLServerColumnEncryptionJavaKeyStoreProvider
. Het geëxporteerde certificaat kan ook worden geïmporteerd in een Java-keystore van het JKS-keystore type.
Nadat u de keytool-vermelding hebt gemaakt, maakt u in de database de metagegevens van de kolomhoofdsleutel aan. Hiervoor zijn de naam van de sleutelarchiefprovider en het sleutelpad nodig. Zie CREATE COLUMN MASTER KEYvoor meer informatie over het maken van metagegevens voor kolomhoofdsleutels. Voor SQLServerColumnEncryptionJavaKeyStoreProvider
is het sleutelpad alleen de alias van de sleutel en de naam van de SQLServerColumnEncryptionJavaKeyStoreProvider
is MSSQL_JAVA_KEYSTORE
. U kunt deze naam ook opvragen met de getName()
openbare API van de SQLServerColumnEncryptionJavaKeyStoreProvider
-klasse.
De T-SQL-syntaxis voor het maken van de kolomhoofdsleutel is:
CREATE COLUMN MASTER KEY [<CMK_name>]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'<key_alias>'
);
Voor de 'AlwaysEncryptedKey' die u eerder hebt gemaakt, is de definitie van de kolomhoofdsleutel:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'AlwaysEncryptedKey'
);
Notitie
De ingebouwde functionaliteit van SQL Server Management Studio kan geen kolomhoofdsleuteldefinities maken voor de Java Key Store. T-SQL-opdrachten moeten programmatisch worden gebruikt.
Een kolomversleutelingssleutel maken voor het Java-sleutelarchief
Sql Server Management Studio of een ander hulpprogramma kan niet worden gebruikt voor het maken van kolomversleutelingssleutels met behulp van kolomhoofdsleutels in het Java-sleutelarchief. De clienttoepassing moet de kolomversleutelingssleutel programmatisch maken met de klasse SQLServerColumnEncryptionJavaKeyStoreProvider
. Zie voor meer informatie Gebruik kolomhoofdsleutelarchiefproviders voor programmatisch sleutelbeheer.
Een aangepaste hoofdsleutelarchiefprovider voor kolommen implementeren
Als u kolomhoofdsleutels wilt opslaan in een sleutelarchief dat niet wordt ondersteund door een bestaande provider, kunt u een aangepaste provider implementeren door de SQLServerColumnEncryptionKeyStoreProvider
Klasse uit te breiden en de provider te registreren met een van de volgende methoden:
SQLServerConnection.registerColumnEncryptionKeyStoreProviders
-
SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection
(toegevoegd in JDBC versie 10.2) -
SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement
(toegevoegd in JDBC versie 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
}
}
Registreer de provider bij SQLServerConnection.registerColumnEncryptionKeyStoreProviders
:
SQLServerColumnEncryptionKeyStoreProvider storeProvider = new MyCustomKeyStore();
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(storeProvider.getName(), storeProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
Prioriteit van cache voor kolomversleutelingssleutel
Deze sectie is van toepassing op JDBC-stuurprogrammaversie 10.2 en hoger.
De kolomversleutelingssleutels (CEK) die zijn ontsleuteld door op maat gemaakte sleutelarchiefproviders die geregistreerd zijn op een verbinding of aanroep, worden door het Microsoft JDBC-stuurprogramma voor SQL Serverniet in de cache opgeslagen. Aangepaste sleutelbeheerproviders moeten hun eigen CEK-cachingmechanisme implementeren.
Vanaf versie 10.2 heeft de SQLServerColumnEncryptionAzureKeyVaultProvider
een eigen CEK-caching-implementatie. Wanneer deze is geregistreerd op een verbindingsexemplaar of instructie-exemplaar, worden CEK's ontsleuteld door een exemplaar van SQLServerColumnEncryptionAzureKeyVaultProvider
gewist wanneer dat exemplaar uit het bereik gaat.
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
Notitie
CEK-caching, geïmplementeerd door aangepaste sleutelbeheerders, wordt door het stuurprogramma uitgeschakeld als het exemplaar van de sleutelbeheerder op globale schaal is geregistreerd in het stuurprogramma volgens de SQLServerConnection.registerColumnEncryptionKeyStoreProviders
-methode. Elke CEK-caching-implementatie moet verwijzen naar de waarde van time-to-live-duur voordat een CEK in de cache wordt opgeslagen en niet in de cache als de waarde nul is. Dit voorkomt dubbele caching en mogelijke verwarring van gebruikers wanneer ze sleutelcaching proberen te configureren. De time-to-live-waarde voor de cache kan worden ingesteld met de methode SQLServerColumnEncryptionKeyStoreProvider.setColumnEncryptionCacheTtl
.
Een aangepaste hoofdsleutelarchiefprovider voor kolommen registreren
Deze sectie is van toepassing op JDBC-stuurprogrammaversie 10.2 en hoger.
Aangepaste hoofdsleutelarchiefproviders kunnen worden geregistreerd bij de driversoftware op drie verschillende niveaus. De prioriteit van de drie registraties is als volgt:
- De registratie per instructie wordt gecontroleerd om te zien of deze niet leeg is.
- Als de registratie per verklaring leeg is, wordt de registratie per verbinding gecontroleerd om te zien of deze niet leeg is.
- Als de registratie per verbinding leeg is, wordt de globale registratie gecontroleerd.
Zodra een sleutelarchiefprovider is gevonden op registratieniveau, het stuurprogramma NIET terugvallen op de andere registraties om naar een provider te zoeken. Als providers zijn geregistreerd, maar de juiste provider niet op een bepaald niveau wordt gevonden, wordt er een uitzondering opgeworpen die alleen de geregistreerde providers bevat in de gecontroleerde registratie.
De ingebouwde hoofdsleutelarchiefprovider voor kolommen die beschikbaar is voor het Windows-certificaatarchief, is vooraf geregistreerd. De Microsoft Java Keystore-provider en Azure Key Vault Keystore-provider kunnen impliciet vooraf worden geregistreerd bij een verbindingsexemplaar als er vooraf referenties worden opgegeven.
De drie registratieniveaus ondersteunen verschillende scenario's bij het opvragen van versleutelde gegevens. De juiste methode kan worden gebruikt om ervoor te zorgen dat een gebruiker van een toepassing toegang heeft tot de platte-tekstgegevens. Toegang tot de niet-versleutelde gegevens vindt alleen plaats als ze de vereiste hoofdsleutel van de kolom kunnen leveren door zich te authentiseren tegen de sleutellocatie die de hoofdsleutel van de kolom bevat.
Toepassingen die een SQLServerConnection
-exemplaar tussen meerdere gebruikers delen, willen mogelijk SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement
gebruiken. Elke gebruiker moet een sleutelarchiefprovider registreren op een SQLServerStatement
exemplaar voordat een query wordt uitgevoerd voor toegang tot een versleutelde kolom. Als de sleutelarchiefprovider toegang heeft tot de vereiste kolomhoofdsleutel in het sleutelarchief dat de opgegeven referenties van de gebruiker gebruikt, slaagt de query.
Toepassingen die een SQLServerConnection
-exemplaar voor elke gebruiker maken, willen mogelijk SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection
gebruiken. Sleutelarchiefproviders die via deze methode zijn geregistreerd, kunnen door de verbinding worden gebruikt voor elke query die toegang tot versleutelde gegevens nodig heeft.
Sleutelarchiefproviders die zijn geregistreerd bij SQLServerConnection.registerColumnEncryptionKeyStoreProviders
gebruiken de identiteit die door de toepassing wordt gegeven bij het verifiëren van het sleutelarchief.
In het volgende voorbeeld ziet u de voorrang van aanbieders van aangepaste kolom meestersleutelopslag die zijn geregistreerd op een verbindingsexemplaar.
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);
}
In het volgende voorbeeld ziet u de prioriteit van providers voor het hoofdsleutelarchief van aangepaste kolommen die zijn geregistreerd op een exemplaar van een instructie:
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);
}
}
Gebruik providers van kolomhoofdsleutelarchieven voor de programmatische voorziening van sleutels
Voor toegang tot versleutelde kolommen vindt en roept het Microsoft JDBC-stuurprogramma voor SQL Server op transparante wijze de juiste provider voor opslag van kolomhoofdsleutels aan om kolomversleutelingssleutels te ontsleutelen. Meestal roept uw normale toepassingscode geen sleutelbeheerders van kolommen aan. U kunt echter programmatisch een provider instantiëren en aanroepen om Always Encrypted-sleutels in te richten en te beheren. Deze stap kan worden uitgevoerd om bijvoorbeeld een versleutelde kolomversleutelingssleutel te genereren en een kolomversleutelingssleutel te ontsleutelen als onderdeel van de hoofdsleutelrotatie van de kolom. Zie Overzicht van Sleutelbeheer voor Always Encryptedvoor meer informatie.
Als u een aangepaste sleutelarchiefprovider gebruikt, is het implementeren van uw eigen hulpprogramma's voor sleutelbeheer mogelijk vereist. Als u sleutels wilt gebruiken die zijn opgeslagen in het Windows-certificaatarchief of in Azure Key Vault, kunt u bestaande hulpprogramma's, zoals SQL Server Management Studio of PowerShell, gebruiken om sleutels te beheren en in te richten. Als u sleutels wilt gebruiken die zijn opgeslagen in het Java Key Store, moet u sleutels programmatisch inrichten. In het volgende voorbeeld ziet u hoe u de SQLServerColumnEncryptionJavaKeyStoreProvider
-klasse gebruikt om de sleutel te versleutelen met een sleutel die is opgeslagen in het Java-sleutelarchief.
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();
}
}
Always Encrypted inschakelen voor toepassingsquery's
De eenvoudigste manier om de versleuteling van parameters en de ontsleuteling van queryresultaten van versleutelde kolommen in te schakelen, is door de waarde van het trefwoord voor de columnEncryptionSetting
verbindingsreeks in te stellen op Enabled
.
De volgende verbindingsreeks is een voorbeeld van het inschakelen van Always Encrypted in het JDBC-stuurprogramma:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;user=<user>;encrypt=true;password=<password>;databaseName=<database>;columnEncryptionSetting=Enabled;";
SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);
De volgende code is een gelijkwaardig voorbeeld voor het gebruik van het SQLServerDataSource
-object:
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 kan ook worden ingeschakeld voor afzonderlijke query's. Zie De impact van de prestaties van Always Encrypted-beheren voor meer informatie. Het inschakelen van Always Encrypted is niet voldoende om versleuteling of ontsleuteling te voltooien. U moet er ook voor zorgen dat:
- De toepassing heeft de
VIEW ANY COLUMN MASTER KEY DEFINITION
- enVIEW ANY COLUMN ENCRYPTION KEY DEFINITION
databasemachtigingen, die vereist zijn voor toegang tot de metagegevens over Always Encrypted-sleutels in de database. Zie Machtigingen in Always Encrypted (Database Engine)voor meer informatie. - De toepassing heeft toegang tot de kolomhoofdsleutel die de kolomversleutelingssleutels beveiligt, waarmee de kolommen van de opgevraagde database worden versleuteld. Als u de Java Key Store-provider wilt gebruiken, moet u extra referenties opgeven in de verbindingsreeks. Zie voor meer informatie Java Key Store-provider gebruiken.
Configureren hoe java.sql.Time-waarden naar de server worden verzonden
De sendTimeAsDatetime
verbindingseigenschap wordt gebruikt om te configureren hoe de waarde java.sql.Time naar de server wordt verzonden. Als deze waarde is ingesteld op onwaar, wordt de tijdwaarde verzonden als een SQL Server-tijdtype. Als deze waarde is ingesteld op true, wordt de tijdwaarde verzonden als een datum/tijd-type. Als een tijdkolom is versleuteld, moet de eigenschap sendTimeAsDatetime
onwaar zijn, omdat versleutelde kolommen de conversie van tijd tot datum/tijd niet ondersteunen. Houd er ook rekening mee dat deze eigenschap standaard waar is, dus als u versleutelde tijdkolommen wilt gebruiken, stelt u deze in op onwaar. Anders gooit de driver een exceptie. Vanaf versie 6.0 van het stuurprogramma heeft de SQLServerConnection
-klasse twee methoden om de waarde van deze eigenschap programmatisch te configureren:
- public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
- openbare boolean getSendTimeAsDatetime()
Zie Configureren hoe java.sql.Time-waarden worden verzonden naar de servervoor meer informatie over deze eigenschap.
Configureren hoe tekenreekswaarden naar de server worden verzonden
De sendStringParametersAsUnicode
verbindingseigenschap wordt gebruikt om te configureren hoe tekenreekswaarden naar SQL Server worden verzonden. Als deze optie is ingesteld op true, worden tekenreeksparameters naar de server verzonden in Unicode-indeling. Als deze optie is ingesteld op onwaar, worden tekenreeksparameters verzonden in niet-Unicode-indeling, zoals ASCII of MBCS, in plaats van Unicode. De standaardwaarde voor deze eigenschap is waar. Wanneer Always Encrypted is ingeschakeld en een char
/varchar
/varchar(max)
kolom is versleuteld, moet de waarde van sendStringParametersAsUnicode
worden ingesteld op false. Als deze eigenschap is ingesteld op true, genereert het stuurprogramma een uitzondering bij het ontsleutelen van gegevens uit een versleutelde char
/varchar
/varchar(max)
kolom met Unicode-tekens. Zie De verbindingseigenschappen instellenvoor meer informatie over deze eigenschap.
Belangrijk
Als sendStringParametersAsUnicode
is ingesteld op true
en unicode-gegevens worden ingevoegd in een char
/varchar
kolom die is versleuteld met Always Encrypted, kunnen gegevensverlies optreden zonder dat er een fout wordt gerapporteerd. Het gegevensverlies kan mogelijk alleen worden gedetecteerd bij het ontsleutelen van de gegevens nadat het is teruggelezen van de server. Een fout zoals 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'.
kan het resultaat zijn.
Het is belangrijk dat u de juiste kolomgegevenstypen gebruikt en het juiste gegevenstype opgeeft voor parameters bij het invoegen van versleutelde gegevens. Als unicode-gegevens worden verwacht, gebruikt u nchar
/nvarchar
kolommen en setNString()
methoden. De server kan geen impliciete gegevensconversies uitvoeren en heeft beperkte mogelijkheden om gegevensfouten te detecteren wanneer Always Encrypted is ingeschakeld.
Gegevens ophalen en wijzigen in versleutelde kolommen
Zodra u Always Encrypted hebt ingeschakeld voor toepassingsquery's, kunt u standaard JDBC-API's gebruiken om gegevens in versleutelde databasekolommen op te halen of te wijzigen. Als uw toepassing over de vereiste databasemachtigingen beschikt en toegang heeft tot de hoofdsleutel van de kolom, versleutelt het stuurprogramma alle queryparameters die zijn gericht op versleutelde kolommen en ontsleutelt het gegevens die worden opgehaald uit versleutelde kolommen.
Als Always Encrypted niet is ingeschakeld, mislukken query's met parameters die zijn gericht op versleutelde kolommen. Query's kunnen nog steeds gegevens ophalen uit versleutelde kolommen zolang de query geen parameters heeft die zijn gericht op versleutelde kolommen. Het stuurprogramma probeert echter geen waarden te ontsleutelen die worden opgehaald uit versleutelde kolommen en de toepassing ontvangt binaire versleutelde gegevens (als bytematrices).
De volgende tabel bevat een overzicht van het gedrag van query's, afhankelijk van of Always Encrypted is ingeschakeld of niet:
Kenmerk van de query | Always Encrypted is ingeschakeld en de toepassing heeft toegang tot de sleutels en sleutelmetagegevens | Always Encrypted is ingeschakeld en de toepassing heeft geen toegang tot de sleutels of sleutelmetagegevens | Always Encrypted is uitgeschakeld |
---|---|---|---|
Query's met parameters die zijn gericht op versleutelde kolommen. | Parameterwaarden worden transparant versleuteld. | Fout | Fout |
Query's die gegevens ophalen uit versleutelde kolommen zonder parameters die zijn gericht op versleutelde kolommen. | Resultaten van versleutelde kolommen worden transparant ontsleuteld. De toepassing ontvangt waarden voor tekst zonder opmaak van de JDBC-gegevenstypen die overeenkomen met de SQL Server-typen die zijn geconfigureerd voor de versleutelde kolommen. | Fout | Resultaten van versleutelde kolommen worden niet ontsleuteld. De toepassing ontvangt versleutelde waarden als bytematrices (byte[]). |
Voorbeelden van versleutelde gegevens invoegen en ophalen
De volgende voorbeelden illustreren het ophalen en wijzigen van gegevens in versleutelde kolommen. In de voorbeelden wordt uitgegaan van de doeltabel met het volgende schema en versleutelde SSN- en BirthDate-kolommen. Als u een kolomhoofdsleutel met de naam 'MyCMK' en een kolomversleutelingssleutel met de naam 'MyCEK' hebt geconfigureerd (zoals beschreven in de voorgaande secties van keystore-providers), kunt u de tabel maken met dit script:
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
Voor elk voorbeeld van Java-code moet u keystore-specifieke code invoegen op de aangegeven locatie.
Een Azure Key Vault-sleutelarchiefprovider gebruiken:
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;";
Een sleutelarchiefprovider voor het Windows-certificaatarchief gebruiken:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";
De keystore-provider voor Java Key Store gebruiken:
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>";
Voorbeeld van het invoegen van gegevens
In dit voorbeeld wordt een rij ingevoegd in de tabel Patiënten. Let op de volgende items:
- Er is niets specifieks voor versleuteling in de voorbeeldcode. Het Microsoft JDBC-stuurprogramma voor SQL Server detecteert en versleutelt automatisch de parameters die zijn gericht op versleutelde kolommen. Dit gedrag maakt versleuteling transparant voor de toepassing.
- De waarden die worden ingevoegd in databasekolommen, inclusief de versleutelde kolommen, worden doorgegeven als parameters met
SQLServerPreparedStatement
. Hoewel parameters optioneel zijn bij het verzenden van waarden naar niet-versleutelde kolommen (hoewel het ten zeerste wordt aanbevolen omdat sql-injectie wordt voorkomen), is het vereist voor waarden die zijn gericht op versleutelde kolommen. Als de waarden die zijn ingevoegd in de versleutelde kolommen zijn doorgegeven als letterlijke waarden die zijn ingesloten in de query-instructie, mislukt de query omdat het stuurprogramma de waarden in de versleutelde doelkolommen niet zou kunnen bepalen en de waarden niet zouden versleutelen. Als gevolg hiervan weigert de server deze als niet compatibel met de versleutelde kolommen. - Alle waarden die door het programma worden afgedrukt, worden zonder opmaak weergegeven, omdat het Microsoft JDBC-stuurprogramma voor SQL Server de gegevens die zijn opgehaald uit de versleutelde kolommen transparant ontsleutelt.
- Als u een opzoekactie uitvoert met een WHERE-component, moet de waarde die wordt gebruikt in de WHERE-component worden doorgegeven als een parameter, zodat het stuurprogramma deze transparant kan versleutelen voordat het naar de database wordt verzonden. In het volgende voorbeeld wordt de SSN doorgegeven als een parameter, maar de LastName wordt doorgegeven als een letterlijke waarde omdat LastName niet is versleuteld.
- De settermethode die wordt gebruikt voor de parameter die is gericht op de SSN-kolom, is
setString()
, die is toegewezen aan hetchar
/varchar
SQL Server-gegevenstype. Als voor deze parameter de gebruikte settermethode issetNString()
, die wordt toegewezen aannchar
/nvarchar
, mislukt de query, omdat Always Encrypted geen conversies van versleuteldenchar
/nvarchar
waarden naar versleuteldechar
/varchar
waarden ondersteunt.
// <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();
}
Voorbeeld van het ophalen van platte tekstgegevens
In het volgende voorbeeld ziet u hoe u gegevens filtert op basis van versleutelde waarden en gegevens uit versleutelde kolommen opvragen. Let op de volgende items:
- De waarde die in de WHERE-component wordt gebruikt om te filteren op de SSN-kolom moet worden doorgegeven als parameter, zodat het Microsoft JDBC-stuurprogramma voor SQL Server deze transparant kan versleutelen voordat deze naar de database wordt verzonden.
- Alle waarden die door het programma worden afgedrukt, worden zonder opmaak weergegeven, omdat het Microsoft JDBC-stuurprogramma voor SQL Server de gegevens die zijn opgehaald uit de kolommen SSN en BirthDate transparant ontsleutelen.
Notitie
als kolommen worden versleuteld met deterministische versleuteling, kunnen query's gelijkheidsvergelijkingen uitvoeren. Zie deterministische versleutelingvoor meer informatie.
// <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();
}
Voorbeeld van versleutelde gegevens ophalen
Als Always Encrypted niet is ingeschakeld, kan een query nog steeds gegevens ophalen uit versleutelde kolommen, zolang de query geen parameters heeft die zijn gericht op versleutelde kolommen.
Het volgende voorbeeld illustreert het ophalen van binaire versleutelde gegevens uit versleutelde kolommen. Let op de volgende items:
- Omdat Always Encrypted niet is ingeschakeld in de verbindingsreeks, retourneert de query versleutelde waarden van SSN en BirthDate als bytematrices (het programma converteert de waarden naar tekenreeksen).
- Een query die gegevens opvraagt uit versleutelde kolommen waarvoor Always Encrypted is uitgeschakeld, kan parameters bevatten, zolang geen van de parameters zich richt op een versleutelde kolom. De volgende query filtert op LastName, die niet is versleuteld in de database. Als de query wordt gefilterd op SSN of BirthDate, mislukt de query.
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();
}
Veelvoorkomende problemen voorkomen bij het maken van query's op versleutelde kolommen
In deze sectie worden veelvoorkomende foutencategorieën beschreven bij het uitvoeren van query's op versleutelde kolommen uit Java-toepassingen en een paar richtlijnen voor het voorkomen van deze kolommen.
Fouten bij het converteren van niet-ondersteunde gegevenstypen
Always Encrypted ondersteunt enkele conversies voor versleutelde gegevenstypen. Zie Always Encrypted (Database Engine) voor de gedetailleerde lijst met ondersteunde typeconversies. Dit is wat u kunt doen om conversiefouten van gegevenstypen te voorkomen. Zorg ervoor dat:
u de juiste settermethoden gebruikt bij het doorgeven van waarden voor parameters die zijn gericht op versleutelde kolommen. Zorg ervoor dat het sql Server-gegevenstype van de parameter exact hetzelfde is als het type van de doelkolom of een conversie van het SQL Server-gegevenstype van de parameter naar het doeltype van de kolom wordt ondersteund. API-methoden zijn toegevoegd aan de
SQLServerPreparedStatement
,SQLServerCallableStatement
enSQLServerResultSet
klassen om parameters door te geven die overeenkomen met specifieke SQL Server-gegevenstypen. Zie Always Encrypted-API-verwijzing voor het JDBC-stuurprogrammavoor een volledige lijst met nieuwe API's. Het niet naleven van definities van gegevenstypen zal waarschijnlijk resulteren in operandtype-conflictfouten. Hier volgen enkele voorbeelden van aanpassingen die nodig kunnen zijn bij het gebruik van Always Encrypted:- U kunt de methode
setTimestamp()
gebruiken om een parameter door te geven aan een niet-versleutelde datetime2- of datetime-kolom. Maar wanneer een kolom is versleuteld, moet u de exacte methode gebruiken die het type kolom in de database aangeeft. GebruiksetTimestamp()
om waarden door te geven aan een versleutelde datum/tijd2-kolom en gebruiksetDateTime()
om waarden door te geven aan een versleutelde datum/tijd-kolom. - U kunt de methode
setBinary()
gebruiken om een parameter door te geven aan een niet-versleuteldevarbinary(max)
ofbinary
kolom. Het stuurprogramma wordt standaard ingesteld op hetBINARY
gegevenstype voorsetBinary()
parameters en de server kan de gegevens impliciet converteren om in te voegen in eenvarbinary(max)
kolom. Maar wanneer eenvarbinary(max)
kolom is versleuteld, moet u een nauwkeuriger type opgeven voor de parametergegevens. Voorbeeld:preparedStatement.setObject(1, binaryData, java.sql.JDBCType.LONGVARBINARY)
- U kunt de methode
de precisie en schaal van parameters die zijn gericht op kolommen van de decimale en numerieke SQL Server-gegevenstypen, zijn hetzelfde als de precisie en schaal die zijn geconfigureerd voor de doelkolom. API-methoden zijn toegevoegd aan de
SQLServerPreparedStatement
,SQLServerCallableStatement
enSQLServerResultSet
klassen om precisie en schaal te accepteren, samen met gegevenswaarden voor parameters/kolommen die decimale en numerieke gegevenstypen vertegenwoordigen. Zie Always Encrypted API-verwijzing voor het JDBC-stuurprogramma voor een volledige lijst met nieuwe/overbelaste API's.- Wanneer u bijvoorbeeld de
BigDecimal
van Java gebruikt als parametertype dat is gericht op een opgegeven decimale kolom in de database, moet u de precisie en schaal opgeven voor desetBigDecimal()
methode ofsetValue()
methode. Als u niet de juiste precisie en schaal opgeeft, kan dit resulteren in een fout zoals hieronder:
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')
- Wanneer u bijvoorbeeld de
De precisie/schaal van fractionele seconden van parameters gericht op kolommen van
datetime2
,datetimeoffset
of SQL Server-tijdgegevenstypen is niet groter dan de precisie/schaal van de fractionele seconden voor de doelkolom in query's die waarden van de doelkolom wijzigen. API-methoden zijn toegevoegd aan deSQLServerPreparedStatement
,SQLServerCallableStatement
enSQLServerResultSet
klassen voor het accepteren van fractionele seconden precisie/schaal, samen met gegevenswaarden voor parameters die deze gegevenstypen vertegenwoordigen. Zie Always Encrypted-API-verwijzing voor het JDBC-stuurprogrammavoor een volledige lijst met nieuwe/overbelaste API's.
Fouten vanwege onjuiste verbindingseigenschappen
In deze sectie wordt beschreven hoe u verbindingsinstellingen correct configureert voor het gebruik van Always Encrypted-gegevens. Omdat versleutelde gegevenstypen beperkte conversies ondersteunen, hebben de sendTimeAsDatetime
- en sendStringParametersAsUnicode
-verbindingsinstellingen de juiste configuratie nodig voor het gebruik van versleutelde kolommen. Zorg ervoor dat:
- sendTimeAsDatetime verbindingsinstelling is ingesteld op onwaar bij het invoegen van gegevens in versleutelde tijdkolommen. Zie Configureren hoe java.sql.Time-waarden naar de server worden verzondenvoor meer informatie.
- sendStringParametersAsUnicode- verbindingsinstelling is ingesteld op true (of als de standaardinstelling blijft) bij het invoegen van gegevens in versleutelde char-/varchar/varchar(max)-kolommen.
Fouten vanwege het doorgeven van tekst zonder opmaak in plaats van versleutelde waarden
Elke waarde die is gericht op een versleutelde kolom, moet in de toepassing worden versleuteld. Een poging om een tekst zonder opmaak in te voegen/te wijzigen of te filteren op een versleutelde kolom resulteert in een fout die vergelijkbaar is met deze:
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'
Om dergelijke fouten te voorkomen, moet u het volgende controleren:
- Always Encrypted is ingeschakeld voor toepassingsquery's die zijn gericht op versleutelde kolommen (voor de verbindingsreeks of voor een specifieke query).
- U gebruikt voorbereide instructies en parameters om gegevens te verzenden die zijn gericht op versleutelde kolommen. In het volgende voorbeeld ziet u een query die onjuist filtert op een letterlijke/constante op een versleutelde kolom (SSN) in plaats van de letterlijke waarde in een parameter door te geven. Deze query mislukt:
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM Customers WHERE SSN='795-73-9838'");
Versleuteling afdwingen voor invoerparameters
Met de functie Versleuteling forceren wordt versleuteling van een parameter afgedwongen met Always Encrypted. Als geforceerde versleuteling wordt gebruikt en SQL Server het stuurprogramma informeert dat de parameter niet hoeft te worden versleuteld, mislukt de query die gebruikmaakt van de parameter. Deze eigenschap biedt extra beveiliging tegen beveiligingsaanvallen waarbij een geïnfecteerde SQL Server onjuiste versleutelingsmetagegevens aan de client biedt, wat kan leiden tot openbaarmaking van gegevens. De set*-methoden in de klassen SQLServerPreparedStatement
en SQLServerCallableStatement
en de update*
methoden in de klasse SQLServerResultSet
zijn overbelast om een booleaanse argument te accepteren om de instelling voor geforceerde versleuteling op te geven. Als de waarde van dit argument onwaar is, dwingt het stuurprogramma versleuteling niet af op parameters. Als force encryption is ingesteld op true, wordt de queryparameter alleen verzonden als de doelkolom is versleuteld en Always Encrypted is ingeschakeld voor de verbinding of voor de instructie. Deze eigenschap biedt een extra beveiligingslaag, zodat het stuurprogramma geen gegevens per ongeluk als tekst zonder opmaak naar SQL Server verzendt wanneer deze naar verwachting wordt versleuteld.
Zie Always Encrypted-API-verwijzing voor het JDBC-stuurprogramma voor meer informatie over de methoden SQLServerPreparedStatement
en SQLServerCallableStatement
die overbelast zijn met de instelling voor geforceerde versleuteling
De invloed van de prestaties van Always Encrypted beheren
Omdat Always Encrypted een versleutelingstechnologie aan de clientzijde is, wordt de meeste prestatieoverhead waargenomen aan de clientzijde, niet in de database. Afgezien van de kosten van versleutelings- en ontsleutelingsbewerkingen, zijn andere bronnen van prestatieoverhead aan de clientzijde:
- Extra opvragingen aan de database toegevoegd om metagegevens van queryparameters op te halen.
- Roept een kolomhoofdsleutelarchief aan om toegang te krijgen tot een kolomhoofdsleutel.
In deze sectie worden de ingebouwde prestatieoptimalisaties in het Microsoft JDBC-stuurprogramma voor SQL Server beschreven en wordt beschreven hoe u de impact van de eerder genoemde twee factoren op prestaties kunt beheren.
Retouren beheren om metagegevens voor queryparameters op te halen
Als Always Encrypted is ingeschakeld voor een verbinding, roept het stuurprogramma standaard sys.sp_describe_parameter_encryption aan voor elke geparameteriseerde query, waarbij de query-instructie (zonder parameterwaarden) wordt doorgegeven aan de database. sys.sp_describe_parameter_encryption analyseert de query-instructie om erachter te komen of er parameters moeten worden versleuteld. Als dat het geval is, retourneert het de versleutelingsgerelateerde informatie waarmee het stuurprogramma parameterwaarden kan versleutelen. Dit gedrag zorgt voor een hoog transparantieniveau voor de clienttoepassing. Zolang de toepassing parameters gebruikt om waarden door te geven die zijn gericht op versleutelde kolommen aan het stuurprogramma, hoeft de toepassing (en de ontwikkelaar van de toepassing) niet te weten welke query's toegang hebben tot versleutelde kolommen.
Always Encrypted instellen op queryniveau
Als u de invloed van de prestaties van het ophalen van versleutelingsmetagegevens voor geparameteriseerde query's wilt beheren, kunt u Always Encrypted inschakelen voor afzonderlijke query's in plaats van deze in te stellen voor de verbinding. Op deze manier kunt u ervoor zorgen dat sys.sp_describe_parameter_encryption alleen wordt aangeroepen voor query's die u weet dat parameters zijn gericht op versleutelde kolommen. Houd er echter rekening mee dat u hierdoor de transparantie van versleuteling vermindert: als u versleutelingseigenschappen van uw databasekolommen wijzigt, moet u mogelijk de code van uw toepassing wijzigen om deze uit te lijnen met de schemawijzigingen.
Als u het "Always Encrypted"-gedrag van afzonderlijke query's wilt beheren, moet u individuele statementobjecten configureren door een Enum, SQLServerStatementColumnEncryptionSetting, door te geven die aangeeft hoe gegevens worden verzonden en ontvangen tijdens het lezen en schrijven van versleutelde kolommen voor die specifieke instructie. Hier volgen enkele nuttige richtlijnen:
Als de meeste query's door een clienttoepassing worden verzonden via versleutelde kolommen voor databaseverbindingen, gebruikt u deze richtlijnen:
- Stel het verbindingsreeks-trefwoord
columnEncryptionSetting
in opEnabled
. - Stel
SQLServerStatementColumnEncryptionSetting.Disabled
in voor afzonderlijke query's die geen toegang hebben tot versleutelde kolommen. Met deze instelling worden zowel het aanroepen vansys.sp_describe_parameter_encryption
als het ontsleutelen van waarden in de resultatenset uitgeschakeld. - Stel
SQLServerStatementColumnEncryptionSetting.ResultSet
in voor afzonderlijke query's waarvoor geen parameters zijn vereist die versleuteling vereisen, maar gegevens ophalen uit versleutelde kolommen. Met deze instelling wordt het aanroepen vansys.sp_describe_parameter_encryption
en parameterversleuteling uitgeschakeld. Met de query worden de resultaten van versleutelingskolommen ontsleuteld.
- Stel het verbindingsreeks-trefwoord
Als de meeste query's die een clienttoepassing verzendt via een databaseverbinding geen toegang hebben tot versleutelde kolommen, gebruikt u deze richtlijnen:
- Stel het trefwoord van de verbindingsreeks
columnEncryptionSetting
in opDisabled
. - Stel
SQLServerStatementColumnEncryptionSetting.Enabled
in voor afzonderlijke query's met parameters die moeten worden versleuteld. Met deze instelling kunt u zowelsys.sp_describe_parameter_encryption
aanroepen als ontsleutelen van queryresultaten die zijn opgehaald uit versleutelde kolommen. - Stel
SQLServerStatementColumnEncryptionSetting.ResultSet
in voor query's die geen parameters hebben waarvoor versleuteling is vereist, maar gegevens ophalen uit versleutelde kolommen. Met deze instelling wordt het aanroepen vansys.sp_describe_parameter_encryption
en parameterversleuteling uitgeschakeld. Met de query worden de resultaten van versleutelingskolommen ontsleuteld.
- Stel het trefwoord van de verbindingsreeks
De SQLServerStatementColumnEncryptionSetting
-instellingen kunnen niet worden gebruikt om versleuteling te omzeilen en toegang te krijgen tot niet-versleutelde gegevens. Zie Always Encrypted-API-verwijzing voor het JDBC-stuurprogrammavoor meer informatie over het configureren van kolomversleuteling op een instructie.
In het volgende voorbeeld is Always Encrypted uitgeschakeld voor de databaseverbinding. De query die de applicatie uitvoert heeft een parameter die gericht is op de niet-versleutelde kolom LastName. De query haalt gegevens op uit de kolommen SSN en BirthDate die beide zijn versleuteld. In dat geval is het aanroepen van sys.sp_describe_parameter_encryption
voor het ophalen van versleutelingsmetagegevens niet vereist. De ontsleuteling van de queryresultaten moet echter worden ingeschakeld, zodat de toepassing waarden voor tekst zonder opmaak kan ontvangen van de twee versleutelde kolommen. De SQLServerStatementColumnEncryptionSetting.ResultSet
-instelling wordt gebruikt om ervoor te zorgen.
// 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();
}
Metagegevens van queryparameters opslaan in cache
Om het aantal retouren naar de database te verminderen, kan het Microsoft JDBC-stuurprogramma voor SQL Server versleutelingsgerelateerde informatie voor queryparameters in de cache opslaan. Vanaf versie 11.2.0 worden versleutelingsgerelateerde gegevens voor parameters die worden geretourneerd door sys.sp_describe_parameter_encryption-aanroepen in de cache opgeslagen door het stuurprogramma als het bijbehorende SQL Server-proces geen beveiligde enclaves gebruikt. Voor caching met behulp van beveiligde enclaves moet de server ondersteuning bieden voor het opnieuw tot stand brengen van de enclavesessie in gevallen waarin de sessie niet meer geldig is.
Caching van sleutels voor kolomversleuteling
Om het aantal aanroepen naar een kolomhoofdsleutelarchief te verminderen om kolomversleutelingssleutels te ontsleutelen, slaat het Microsoft JDBC-stuurprogramma voor SQL Server de versleutelingssleutels voor kolommen in het geheugen op in de cache. Nadat de driver de waarde van de versleutelde kolomversleutelsleutel van de metagegevens van de database heeft ontvangen, probeert de driver eerst de plaintext kolomversleutelsleutel te vinden die overeenkomt met de versleutelde sleutelwaarde. Het stuurprogramma roept de sleutelarchief met de kolomhoofdsleutel alleen aan als de versleutelde waarde voor kolomversleutelingssleutel niet in de cache kan worden gevonden.
U kunt een tijd-tot-leven-waarde configureren voor de vermeldingen van kolomversleutels in de cache met de API, setColumnEncryptionKeyCacheTtl()
, in de klasse SQLServerConnection
. De standaard levensduur voor de vermeldingen van de kolomsleutels in de cache is twee uur. Gebruik een waarde van 0 om caching uit te schakelen. Als u een time-to-live-waarde wilt instellen, gebruikt u de volgende API:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (int columnEncryptionKeyCacheTTL, TimeUnit unit)
Als u bijvoorbeeld een time-to-live-waarde van 10 minuten wilt instellen, gebruikt u:
SQLServerConnection.setColumnEncryptionKeyCacheTtl (10, TimeUnit.MINUTES)
Alleen DAGEN, UREN, MINUTEN of SECONDEN worden ondersteund als tijdseenheid.
Versleutelde gegevens kopiëren met SQLServerBulkCopy
Met SQLServerBulkCopy
kunt u gegevens kopiëren die al zijn versleuteld en opgeslagen in de ene tabel naar een andere tabel zonder de gegevens te ontsleutelen. Ga hiervoor als volgende te werk:
- Zorg ervoor dat de versleutelingsconfiguratie van de doeltabel identiek is aan de configuratie van de brontabel. In het bijzonder moeten beide tabellen dezelfde kolommen hebben die zijn versleuteld en moeten de kolommen worden versleuteld met dezelfde versleutelingstypen en dezelfde versleutelingssleutels. Als een doelkolom anders is versleuteld dan de bijbehorende bronkolom, kunt u de gegevens in de doeltabel niet ontsleutelen na de kopieerbewerking. De gegevens zijn beschadigd.
- Configureer zowel databaseverbindingen met de brontabel als de doeltabel zonder Always Encrypted ingeschakeld.
- Stel de optie
allowEncryptedValueModifications
in. Zie Bulkkopie gebruiken met het JDBC-stuurprogrammavoor meer informatie.
Notitie
Wees voorzichtig bij het opgeven van AllowEncryptedValueModifications
omdat deze optie kan leiden tot beschadigde database omdat het Microsoft JDBC-stuurprogramma voor SQL Server niet controleert of de gegevens inderdaad zijn versleuteld of als deze correct zijn versleuteld met hetzelfde versleutelingstype, algoritme en sleutel als de doelkolom.