Verwenden von Always Encrypted mit dem JDBC-TreiberUsing Always Encrypted with the JDBC driver

HerunterladenJDBC-Treiber herunterladenDownloadDownload JDBC Driver

Diese Seite enthält Informationen zum Entwickeln von Java-Anwendungen mithilfe von Always Encrypted und dem Microsoft JDBC-Treiber 6,0 (oder höher) für SQL Server.This page provides information on how to develop Java applications using Always Encrypted and the Microsoft JDBC Driver 6.0 (or higher) for SQL Server.

Always Encrypted ermöglicht Clients das Verschlüsseln von vertraulichen Daten in einer Weise, dass weder die Daten noch die Verschlüsselungsschlüssel zu irgendeinem Zeitpunkt gegenüber SQL Server oder Azure SQL-Datenbank offengelegt werden.Always Encrypted allows clients to encrypt sensitive data and never reveal the data or the encryption keys to SQL Server or Azure SQL Database. Ein Treiber, bei dem Always Encrypted aktiviert ist, z.B. der Microsoft JDBC-Treiber 6.0 (oder höher) für SQL Server, erreicht dieses Verhalten durch die transparente Ver- und Entschlüsselung von sensiblen Daten in der Clientanwendung.An Always Encrypted enabled driver, such as the Microsoft JDBC Driver 6.0 (or higher) for SQL Server, achieves this behavior by transparently encrypting and decrypting sensitive data in the client application. Der Treiber ermittelt automatisch, welche Abfrage Parameter Always Encrypted Daten Bank Spalten entsprechen, und verschlüsselt die Werte dieser Parameter, bevor Sie an SQL Server oder Azure SQL-Datenbank gesendet werden.The driver automatically determines which query parameters correspond to Always Encrypted database columns, and encrypts the values of those parameters before it sends them to SQL Server or Azure SQL Database. Auf ähnliche Weise entschlüsselt der Treiber die Daten transparent, die von verschlüsselten Datenbankspalten in Abfrageergebnissen empfangen werden.Similarly, the driver transparently decrypts data retrieved from encrypted database columns in query results. Weitere Informationen finden Sie unter Always encrypted (Datenbank-Engine) und Always Encrypted-API-Referenz für den JDBC-Treiber.For more information, see Always Encrypted (Database Engine) and Always Encrypted API reference for the JDBC driver.

VoraussetzungenPrerequisites

  • Stellen Sie sicher, dass der Microsoft JDBC-Treiber 6,0 (oder höher) für SQL Server auf dem Entwicklungs Computer installiert ist.Make sure Microsoft JDBC Driver 6.0 (or higher) for SQL Server is installed on your development machine.

  • Laden Sie die Richtliniendateien Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction herunter und installieren Sie sie.Download and install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Achten Sie darauf, die in der ZIP-Datei enthaltene Infodatei zu lesen, um Installationsanweisungen und relevante Details zu möglichen Export-/Importproblemen zu erhalten.Be sure to read the Readme included in the zip file for installation instructions and relevant details on possible export/import issues.

Arbeiten mit SpaltenhauptschlüsselspeichernWorking with column master key stores

Zum Verschlüsseln oder Entschlüsseln von Daten für verschlüsselte Spalten SQL Server die Spalten Verschlüsselungsschlüssel verwaltet.To encrypt or decrypt data for encrypted columns, SQL Server maintains column encryption keys. Spaltenverschlüsselungsschlüssel werden in der verschlüsselten Form in den Datenbankmetadaten gespeichert.Column encryption keys are stored in encrypted form in the database metadata. Jeder Spaltenverschlüsselungsschlüssel weist einen entsprechenden Spaltenhauptschlüssel auf, mit dem der Spaltenverschlüsselungsschlüssel verschlüsselt wurde.Each column encryption key has a corresponding column master key that is used to encrypt the column encryption key. Die Daten Bank Metadaten enthalten nicht die Spalten Hauptschlüssel.The database metadata doesn't contain the column master keys. Diese Schlüssel werden nur vom Client gespeichert.Those keys are only held by the client. Die Daten Bank Metadaten enthalten jedoch Informationen dazu, wo die Spalten Hauptschlüssel relativ zum Client gespeichert werden.However the database metadata does contain information about where the column master keys are stored relative to the client. Beispielsweise können die Daten Bank Metadaten besagen, dass der Keystore, der einen Spalten Hauptschlüssel enthält, der Windows-Zertifikat Speicher ist, und das spezifische Zertifikat, das zum Verschlüsseln und entschlüsseln verwendet wird, sich in einem bestimmten Pfad innerhalb des Windows-Zertifikat Speicher befindet.For example, the database metadata may say that the keystore holding a column master key is the Windows Certificate Store and the specific certificate used to encrypt and decrypt is located at a specific path within the Windows Certificate Store. Wenn der Client Zugriff auf dieses Zertifikat im Windows-Zertifikat Speicher hat, kann er das Zertifikat abrufen.If the client has access to that certificate in the Windows Certificate Store, it can obtain the certificate. Das Zertifikat kann dann verwendet werden, um den Spalten Verschlüsselungsschlüssel zu entschlüsseln.The certificate can then be used to decrypt the column encryption key. Dieser Verschlüsselungsschlüssel kann zum Entschlüsseln oder Verschlüsseln von Daten für verschlüsselte Spalten verwendet werden, die diesen Spalten Verschlüsselungsschlüssel verwenden.Then that encryption key can be used to decrypt or encrypt data for encrypted columns that use that column encryption key.

Der Microsoft JDBC-Treiber für SQL Server kommuniziert mit einem Keystore unter Verwendung eines Spalten Hauptschlüssel-Speicher Anbieters, bei dem es sich um eine Instanz einer Klasse handelt, die von sqlservercolumnencryptionkeystoreproviderabgeleitet ist.The Microsoft JDBC Driver for SQL Server communicates with a keystore using a column master key store provider, which is an instance of a class derived from SQLServerColumnEncryptionKeyStoreProvider.

Verwenden integrierter Spaltenhauptschlüssel-SpeicheranbieterUsing built-in column master key store providers

Der Microsoft JDBC-Treiber für SQL Server verfügt über die folgenden integrierten Spalten Hauptschlüssel-Speicher Anbieter.The Microsoft JDBC Driver for SQL Server comes with the following built-in column master key store providers. Einige dieser Anbieter sind bereits mit den spezifischen Anbieter Namen (für die Suche nach dem Anbieter) registriert, und einige erfordern entweder zusätzliche Anmelde Informationen oder eine explizite Registrierung.Some of these providers are pre-registered with the specific provider names (used to look up the provider) and some require either additional credentials or explicit registration.

ClassClass und BeschreibungDescription Anbietername (Suche)Provider (lookup) name Ist bereits registriert?Is pre-registered?
SQLServerColumnEncryptionAzureKeyVaultProviderSQLServerColumnEncryptionAzureKeyVaultProvider Ein Anbieter für einen Keystore für die Azure Key Vault.A provider for a keystore for the Azure Key Vault. AZURE_KEY_VAULTAZURE_KEY_VAULT NeinNo
SQLServerColumnEncryptionCertificateStoreProviderSQLServerColumnEncryptionCertificateStoreProvider Ein Anbieter für den Windows-Zertifikatspeicher.A provider for the Windows Certificate Store. MSSQL_CERTIFICATE_STOREMSSQL_CERTIFICATE_STORE JaYes
SQLServerColumnEncryptionJavaKeyStoreProviderSQLServerColumnEncryptionJavaKeyStoreProvider Ein Anbieter für den Java-KeyStoreA provider for the Java keystore MSSQL_JAVA_KEYSTOREMSSQL_JAVA_KEYSTORE JaYes

Bei den vorab registrierten Keystore-Anbietern müssen Sie keine Änderungen am Anwendungscode vornehmen, um diese Anbieter zu verwenden. Beachten Sie jedoch die folgenden Elemente:For the pre-registered keystore providers, you don't need to make any application code changes to use these providers but note the following items:

  • Sie (oder Ihr Datenbankadministrator) müssen sicherstellen, dass der in den Metadaten des Spaltenhauptschlüssels konfigurierte Anbietername richtig ist und der Pfad des Spaltenhauptschlüssels dem Schlüsselpfadformat entspricht, das für einen angegebenen Anbieter gültig ist.You (or your DBA) need to make sure the provider name configured in the column master key metadata is correct and the column master key path complies with the key path format that is valid for a given provider. Es wird empfohlen, dass Sie die Schlüssel mithilfe von Tools wie SQL Server Management Studio konfigurieren, die die gültigen Anbieternamen und Schlüsselpfade automatisch generieren, wenn die Anweisung CREATE COLUMN MASTER KEY (Transact-SQL) ausgegeben wird.It's recommended that you configure the keys using tools, such as SQL Server Management Studio, which automatically generates the valid provider names and key paths when issuing the CREATE COLUMN MASTER KEY (Transact-SQL) statement.
  • Stellen Sie sicher, dass die Anwendung auf den Schlüssel im Schlüsselspeicher zugreifen kann.Ensure your application can access the key in the keystore. Diese Task kann das Gewähren des Zugriffs auf den Schlüssel und/oder Schlüsselspeicher für die Anwendung (abhängig vom Schlüsselspeicher) oder das Ausführen anderer wichtiger speicherspezifischer Konfigurationsschritte einbeziehen.This task may involve granting your application access to the key and/or the keystore, depending on the keystore, or performing other keystore-specific configuration steps. Beispielsweise müssen Sie für die Verwendung von sqlservercolumnencryptionjavakeystoreprovider den Speicherort und das Kennwort des Keystores in den Verbindungs Eigenschaften angeben.For example, for using the SQLServerColumnEncryptionJavaKeyStoreProvider, you need to provide the location and the password of the keystore in the connection properties.

Alle diese Keystore-Anbieter werden in den folgenden Abschnitten ausführlicher beschrieben.All of these keystore providers are described in more detail in the sections that follow. Sie müssen nur einen Keystore-Anbieter implementieren, um Always Encrypted zu verwenden.You only need to implement one keystore provider to use Always Encrypted.

Verwenden des Azure Key Vault-AnbietersUsing Azure Key Vault provider

Azure Key Vault ist eine praktische Möglichkeit zum Speichern von Spaltenhauptschlüsseln für Always Encrypted (insbesondere, wenn Ihre Anwendung in Azure gehostet wird).Azure Key Vault is a convenient option to store and manage column master keys for Always Encrypted (especially if your application is hosted in Azure). Der Microsoft JDBC-Treiber für SQL Server enthält den integrierten Anbieter sqlservercolumnencryptionazurekeyvaultprovider für Anwendungen, die in Azure Key Vault gespeicherte Schlüssel haben.The Microsoft JDBC Driver for SQL Server includes a built-in provider, SQLServerColumnEncryptionAzureKeyVaultProvider, for applications that have keys stored in Azure Key Vault. Der Name dieses Anbieters ist AZURE_KEY_VAULT.The name of this provider is AZURE_KEY_VAULT. Um den Azure Key Vault Store-Anbieter zu verwenden, muss ein Anwendungsentwickler den Tresor und die Schlüssel in Azure Key Vault erstellen und eine APP-Registrierung in Azure Active Directory erstellen.In order to use the Azure Key Vault store provider, an application developer needs to create the vault and the keys in Azure Key Vault and create an App registration in Azure Active Directory. Der registrierten Anwendung müssen die Berechtigungen Get, entschlüsseln, verschlüsseln, Unwrap Key, Wrap Key und Verify in den Zugriffsrichtlinien erteilt werden, die für den Schlüssel Tresor definiert sind, der für die Verwendung mit Always Encrypted erstellt wurde.The registered application must be granted Get, Decrypt, Encrypt, Unwrap Key, Wrap Key, and Verify permissions in the Access policies defined for the key vault created for use with Always Encrypted. Weitere Informationen zum Einrichten des Schlüssel Tresors und zum Erstellen eines Spalten Hauptschlüssels finden Sie unter Azure Key Vault Schritt Weise Anleitung und Erstellen von Spalten Hauptschlüsseln in Azure Key Vault.For more information on how to set up the key vault and create a column master key, see Azure Key Vault - Step by Step and Creating Column Master Keys in Azure Key Vault.

Wenn Sie in den Beispielen auf dieser Seite mithilfe SQL Server Management Studio einen Azure Key Vault basierten Spalten Hauptschlüssel und einen Spalten Verschlüsselungsschlüssel erstellt haben, könnte das T-SQL-Skript zum erneuten Erstellen in etwa wie in diesem Beispiel mit den eigenen spezifischen KEY_PATH und ENCRYPTED_VALUEaussehen:For the examples on this page, if you've created an Azure Key Vault based column master key and column encryption key by using SQL Server Management Studio, the T-SQL script to re-create them might look similar to this example with its own specific KEY_PATH and ENCRYPTED_VALUE:

CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
    KEY_STORE_PROVIDER_NAME = N'AZURE_KEY_VAULT',
    KEY_PATH = N'https://<MyKeyValutName>.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...
)

Um das Azure Key Vault verwenden zu können, müssen Client Anwendungen sqlservercolumnencryptionazurekeyvaultprovider instanziieren und Sie beim Treiber registrieren.To use the Azure Key Vault, client applications need to instantiate the SQLServerColumnEncryptionAzureKeyVaultProvider and register it with the driver.

Im folgenden finden Sie ein Beispiel für die Initialisierung von sqlservercolumnencryptionazurekeyvaultprovider:Here is an example of initializing SQLServerColumnEncryptionAzureKeyVaultProvider:

SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);

ClientID ist die Anwendungs-ID einer APP-Registrierung in einer Azure Active Directory Instanz.clientID is the Application ID of an App registration in an Azure Active Directory instance. clientkey ist ein Schlüssel Kennwort, das unter dieser Anwendung registriert ist und API-Zugriff auf die Azure Key Vault bietet.clientKey is a Key Password registered under that Application, which provides API access to the Azure Key Vault.

Nachdem die Anwendung eine Instanz von sqlservercolumnencryptionazurekeyvaultprovider erstellt hat, muss Sie mithilfe der SQLServerConnection. registercolumnencryptionkeystoreproviders ()-Methode bei dem Treiber registriert werden.After the application creates an instance of SQLServerColumnEncryptionAzureKeyVaultProvider, the application must register the instance with the driver using the SQLServerConnection.registerColumnEncryptionKeyStoreProviders() method. Es wird dringend empfohlen, die Instanz mit dem Standardnamen für die Suche (AZURE_KEY_VAULT) zu registrieren, der durch Aufrufen der sqlservercolumnencryptionazurekeyvaultprovider. GetName ()-API abgerufen werden kann.It's highly recommended that the instance is registered using the default lookup name, AZURE_KEY_VAULT, which can be obtained by calling the SQLServerColumnEncryptionAzureKeyVaultProvider.getName() API. Wenn Sie den Standardnamen verwenden, können Sie Tools wie SQL Server Management Studio oder PowerShell verwenden, um Always Encrypted Schlüssel bereitzustellen und zu verwalten (die Tools verwenden den Standardnamen, um das Metadatenobjekt in den Spalten Hauptschlüssel zu generieren).Using the default name will allow you to use tools such as SQL Server Management Studio or PowerShell to provision and manage Always Encrypted keys (the tools use the default name to generate the metadata object to column master key). Im folgenden Beispiel wird die Registrierung des Azure Key Vault Anbieters veranschaulicht.The following example shows registering the Azure Key Vault provider. Weitere Informationen zur SQLServerConnection. registercolumnencryptionkeystoreproviders ()-Methode finden Sie unter Always Encrypted-API-Referenz für den JDBC-Treiber.For more information on the SQLServerConnection.registerColumnEncryptionKeyStoreProviders() method, see Always Encrypted API Reference for the JDBC Driver.

Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);

Wichtig

Wenn Sie den Azure Key Vault Keystore-Anbieter verwenden, hat die Azure Key Vault Implementierung des JDBC-Treibers Abhängigkeiten von diesen Bibliotheken (von GitHub), die in der Anwendung enthalten sein müssen:If you use the Azure Key Vault keystore provider, the Azure Key Vault implementation of the JDBC driver has dependencies on these libraries (from GitHub) which must be included with your application:

azure-sdk-for-javaazure-sdk-for-java

azure-activedirectory-library-for-java librariesazure-activedirectory-library-for-java libraries

Ein Beispiel für das einschließen dieser Abhängigkeiten in ein Maven-Projekt finden Sie unter Herunterladen von ADAL4J-und AKV-Abhängigkeiten mit Apache Maven .For an example of how to include these dependencies in a Maven project, see Download ADAL4J And AKV Dependencies with Apache Maven

Verwenden des Windows-ZertifikatspeicheranbietersUsing Windows Certificate Store provider

Mit „SqlColumnEncryptionCertificateStoreProvider“ können Spaltenhauptschlüssel im Windows-Zertifikatspeicher gespeichert werden.The SQLServerColumnEncryptionCertificateStoreProvider can be used to store column master keys in the Windows Certificate Store. Verwenden Sie den SQL Server Management Studio-Always Encrypted-Assistenten (SSMS) oder andere unterstützte Tools, um die Spalten Hauptschlüssel-und Spalten Verschlüsselungsschlüssel-Definitionen in der-Datenbank zu erstellen.Use the SQL Server Management Studio (SSMS) Always Encrypted wizard or other supported tools to create the column master key and column encryption key definitions in the database. Der gleiche Assistent kann verwendet werden, um ein selbst signiertes Zertifikat im Windows-Zertifikat Speicher zu generieren, das als Spalten Hauptschlüssel für die Always Encrypted Daten verwendet werden kann.The same wizard can be used to generate a self signed certificate in the Windows Certificate Store that can be used as a column master key for the Always Encrypted data. Weitere Informationen zum Spaltenhauptschlüssel und der T-SQL-Syntax für den Spaltenverschlüsselungsschlüssel finden Sie unter ERSTELLEN DES SPALTENHAUPTSCHLÜSSELS bzw. ERSTELLEN DES SPALTENVERSCHLÜSSELUNGSSCHLÜSSELS.For more information on column master key and column encryption key T-SQL syntax, see CREATE COLUMN MASTER KEY and CREATE COLUMN ENCRYPTION KEY respectively.

Der Name des sqlservercolumnencryptioncertifikatestoreprovider ist MSSQL_CERTIFICATE_STORE und kann von der GetName ()-API des Anbieter Objekts abgefragt werden.The name of the SQLServerColumnEncryptionCertificateStoreProvider is MSSQL_CERTIFICATE_STORE and can be queried by the getName() API of the provider object. Sie wird automatisch vom Treiber registriert und kann nahtlos ohne Änderung der Anwendung verwendet werden.It's automatically registered by the driver and can be used seamlessly without any application change.

Wenn Sie in den Beispielen auf dieser Seite mithilfe SQL Server Management Studio einen Windows-Zertifikat Speicher basierten Spalten Hauptschlüssel und einen Spalten Verschlüsselungsschlüssel erstellt haben, könnte das T-SQL-Skript zur erneuten Erstellung in etwa wie in diesem Beispiel mit den eigenen spezifischen KEY_PATH und ENCRYPTED_VALUEaussehen:For the examples on this page, if you've created a Windows Certificate Store based column master key and column encryption key by using SQL Server Management Studio, the T-SQL script to re-create them might look similar to this example with its own specific KEY_PATH and 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...
)

Wichtig

Während die anderen Keystore-Anbieter in diesem Artikel auf allen Plattformen verfügbar sind, die vom Treiber unterstützt werden, ist die sqlservercolumnencryptioncertifikatestoreprovider-Implementierung des JDBC-Treibers nur auf Windows-Betriebssystemen verfügbar.While the other keystore providers in this article are available on all platforms supported by the driver, the SQLServerColumnEncryptionCertificateStoreProvider implementation of the JDBC driver is available on Windows operating systems only. Es besteht eine Abhängigkeit von der sqljdbc_auth. dll, die im Treiber Paket verfügbar ist.It has a dependency on the sqljdbc_auth.dll that is available in the driver package. Wenn Sie diesen Anbieter verwenden möchten, müssen Sie die Datei „sqljdbc_auth.dll“ in ein Verzeichnis im Windows-Systempfad des Computers kopieren, auf dem der JDBC-Treiber installiert ist.To use this provider, copy the sqljdbc_auth.dll file to a directory on the Windows system path on the computer where the JDBC driver is installed. Alternativ können Sie mit der java.libary.path-Systemeigenschaft das Verzeichnis von „sqljdbc_auth.dll“ angeben.Alternatively you can set the java.library.path system property to specify the directory of the sqljdbc_auth.dll. Wenn Sie eine 32-Bit-JVM (Java Virtual Machine) ausführen, verwenden Sie die Datei sqljdbc_auth.dll im Ordner x86, auch wenn es sich bei dem Betriebssystem um die x64-Version handelt.If you are running a 32-bit Java Virtual Machine (JVM), use the sqljdbc_auth.dll file in the x86 folder, even if the operating system is the x64 version. Wenn Sie eine 64-Bit-JVM mit einem x64-Prozessor ausführen, verwenden Sie die Datei „sqljdbc_auth.dll“ im Ordner „x64“.If you are running a 64-bit JVM on a x64 processor, use the sqljdbc_auth.dll file in the x64 folder. Wenn Sie beispielsweise die 32-Bit-JVM verwenden und der JDBC-Treiber im Standardverzeichnis installiert ist, können Sie den Speicherort der DLL beim Start der Java-Anwendung mit dem folgenden VM-Argument (Virtual Machine) angeben: -Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86For example, if you are using the 32-bit JVM and the JDBC driver is installed in the default directory, you can specify the location of the DLL by using the following virtual machine (VM) argument when the Java application is started: -Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86

Verwenden des Java-Schlüsselspeicher AnbietersUsing Java Key Store provider

Der JDBC-Treiber ist mit einer integrierten Schlüsselspeicheranbieter-Implementierung für den Java Key Store ausgestattet.The JDBC driver comes with a built-in keystore provider implementation for the Java Key Store. Wenn die keystoreauthentication -Verbindungs Zeichenfolgen-Eigenschaft in der Verbindungs Zeichenfolge vorhanden und auf "javakeystorepassword" festgelegt ist, instanziiert und registriert der Treiber den Anbieter für den Java-Schlüsselspeicher automatisch.If the keyStoreAuthentication connection string property is present in the connection string and it's set to "JavaKeyStorePassword", the driver automatically instantiates and registers the provider for Java Key Store. Der Name des Java-Schlüsselspeicher Anbieters ist MSSQL_JAVA_KEYSTORE.The name of the Java Key Store provider is MSSQL_JAVA_KEYSTORE. Dieser Name kann auch mit der sqlservercolumnencryptionjavakeystoreprovider. GetName ()-API abgefragt werden.This name can also be queried by using the SQLServerColumnEncryptionJavaKeyStoreProvider.getName() API.

Es gibt drei Eigenschaften der Verbindungs Zeichenfolge, die es einer Client Anwendung ermöglichen, die Anmelde Informationen anzugeben, die der Treiber für die Authentifizierung beim Java-Schlüsselspeicher benötigt.There are three connection string properties that allow a client application to specify the credentials the driver needs to authenticate to the Java Key Store. Der Treiber initialisiert den Anbieter auf der Grundlage der Werte dieser drei Eigenschaften in der Verbindungs Zeichenfolge.The driver initializes the provider based on the values of these three properties in the connection string.

keystoreauthentication: Identifiziert den zu verwendenden Java-Schlüsselspeicher.keyStoreAuthentication: Identifies the Java Key Store to use. Mit dem Microsoft JDBC-Treiber 6,0 und höher für SQL Server können Sie sich nur über diese Eigenschaft beim Java-Schlüsselspeicher authentifizieren.With Microsoft JDBC Driver 6.0 and higher for SQL Server, you can authenticate to the Java Key Store only through this property. Für den Java-Schlüsselspeicher muss der Wert für diese Eigenschaft JavaKeyStorePasswordwerden.For the Java Key Store, the value for this property must be JavaKeyStorePassword.

keystoreloation: Der Pfad zur Java-Schlüsselspeicher Datei, in der der Spalten Hauptschlüssel gespeichert wird.keyStoreLocation: The path to the Java Key Store file that stores the column master key. Der Pfad enthält den Keystore-Dateinamen.The path includes the keystore filename.

keystoresecret: Der geheime Schlüssel bzw. das Kennwort, das für den Keystore und für den Schlüssel verwendet werden soll.keyStoreSecret: The secret/password to use for the keystore as well as for the key. Zum Verwenden des Java-Schlüsselspeicher müssen der keystore und das Schlüssel Kennwort identisch sein.For using the Java Key Store, the keystore and the key password must be the same.

Im folgenden finden Sie ein Beispiel für die Angabe dieser Anmelde Informationen in der Verbindungs Zeichenfolge:Here is an example of providing these credentials in the connection string:

String connectionUrl = "jdbc:sqlserver://<server>:<port>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=<path_to_the_keystore_file>;keyStoreSecret=<keystore_key_password>";

Sie können diese Einstellungen auch mit dem SQLServerDataSource-Objekt erhalten oder festlegen.You can also get or set these settings using the SQLServerDataSource object. Weitere Informationen finden Sie unter Always Encrypted-API-Referenz für den JDBC-Treiber.For more information, see Always Encrypted API Reference for the JDBC Driver.

Der JDBC-Treiber instanziiert automatisch sqlservercolumnencryptionjavakeystoreprovider, wenn diese Anmelde Informationen in den Verbindungs Eigenschaften vorhanden sind.The JDBC driver automatically instantiates the SQLServerColumnEncryptionJavaKeyStoreProvider when these credentials are present in connection properties.

Erstellen eines Spalten Hauptschlüssels für den Java-SchlüsselspeicherCreating a column master key for the Java Key Store

Sqlservercolumnencryptionjavakeystoreprovider kann mit jert-oder PKCS12 Keystore-Typen verwendet werden.The SQLServerColumnEncryptionJavaKeyStoreProvider can be used with JKS or PKCS12 keystore types. Zum Erstellen oder Importieren eines Schlüssels, der mit diesem Anbieter verwendet werden soll, verwenden Sie das Java keytool -Hilfsprogramm.To create or import a key to use with this provider use the Java keytool utility. Der Schlüssel muss das gleiche Kennwort wie der Keystore selbst aufweisen.The key must have the same password as the keystore itself. Im folgenden finden Sie ein Beispiel für das Erstellen eines öffentlichen Schlüssels und des zugehörigen privaten Schlüssels mit dem Hilfsprogramm "keytool":Here is an example of how to create a public key and its associated private key using the keytool utility:

keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.jks -storepass mypassword -validity 360 -keysize 2048 -storetype jks

Mit diesem Befehl wird ein öffentlicher Schlüssel erstellt und in ein selbst signiertes X. 509-Zertifikat umschlossen, das zusammen mit dem zugehörigen privaten Schlüssel im Keystore "keystore. jert" gespeichert ist.This command creates a public key and wraps it in an X.509 self signed certificate, which is stored in the keystore 'keystore.jks' along with its associated private key. Dieser Eintrag im Keystore wird durch den Alias "alwaysencryptedkey" identifiziert.This entry in the keystore is identified by the alias 'AlwaysEncryptedKey'.

Im folgenden finden Sie ein Beispiel für das gleiche mit einem PKCS12 Store-Typ:Here is an example of the same using a PKCS12 store type:

keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.pfx -storepass mypassword -validity 360 -keysize 2048 -storetype pkcs12 -keypass mypassword

Wenn der Keystore den Typ PKCS12 hat, fordert das keytool-Hilfsprogramm nicht zur Eingabe eines Schlüssel Kennworts auf, und das Schlüssel Kennwort muss mit der Option-keypass angegeben werden, da sqlservercolumnencryptionjavakeystoreprovider erfordert, dass der keystore und der Schlüssel identisch sind. anmelden.If the keystore is of type PKCS12, the keytool utility doesn't prompt for a key password and the key password needs to be provided with -keypass option as the SQLServerColumnEncryptionJavaKeyStoreProvider requires that the keystore and the key have the same password.

Sie können ein Zertifikat auch aus dem Windows-Zertifikat Speicher im PFX-Format exportieren und mit sqlservercolumnencryptionjavakeystoreprovider verwenden.You can also export a certificate from the Windows Certificate store in .pfx format and use that with the SQLServerColumnEncryptionJavaKeyStoreProvider. Das exportierte Zertifikat kann auch in den Java-Schlüsselspeicher als jert-Keystore-Typ importiert werden.The exported certificate can also be imported to the Java Key Store as a JKS keystore type.

Nachdem Sie den Eintrag keytool erstellt haben, erstellen Sie die Metadaten des Spalten Hauptschlüssels in der Datenbank, die den Namen des Keystore-Anbieters und den Schlüssel Pfad benötigt.After creating the keytool entry, create the column master key metadata in the database, which needs the keystore provider name and the key path. Weitere Informationen zum Erstellen von Spalten Hauptschlüssel-metadatendaten finden Sie unter Create Column Master Key.For more information on how to create column master key meta data, see CREATE COLUMN MASTER KEY. Für sqlservercolumnencryptionjavakeystoreprovider ist der Schlüssel Pfad nur der Alias des Schlüssels, und der Name des sqlservercolumnencryptionjavakeystoreprovider ist "MSSQL_JAVA_KEYSTORE".For SQLServerColumnEncryptionJavaKeyStoreProvider, the key path is just the alias of the key and the name of the SQLServerColumnEncryptionJavaKeyStoreProvider is 'MSSQL_JAVA_KEYSTORE'. Sie können diesen Namen auch mit der öffentlichen GetName ()-API der sqlservercolumnencryptionjavakeystoreprovider-Klasse Abfragen.You can also query this name using the getName() public API of the SQLServerColumnEncryptionJavaKeyStoreProvider class.

Die T-SQL-Syntax zum Erstellen des Spalten Hauptschlüssels lautet:The T-SQL syntax for creating the column master key is:

CREATE COLUMN MASTER KEY [<CMK_name>]
WITH
(
    KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
    KEY_PATH = N'<key_alias>'
)

Für "alwaysencryptedkey", das oben erstellt wurde, lautet die Definition des Spalten Hauptschlüssels wie folgt:For the 'AlwaysEncryptedKey' created above, the column master key definition would be:

CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
    KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
    KEY_PATH = N'AlwaysEncryptedKey'
)

Hinweis

Mit der integrierten SQL Server Management Studio-Funktionalität können keine Spalten Hauptschlüssel-Definitionen für den Java-Schlüsselspeicher erstellt werden.The built-in SQL Server management Studio functionality cannot create column master key definitions for the Java Key Store. T-SQL-Befehle müssen Programm gesteuert verwendet werden.T-SQL commands must be used programmatically.

Erstellen eines Spalten Verschlüsselungsschlüssels für den Java-SchlüsselspeicherCreating a column encryption key for the Java Key Store

Die SQL Server Management Studio oder andere Tools können nicht zum Erstellen von Spalten Verschlüsselungsschlüsseln verwendet werden, die Spalten Hauptschlüssel im Java-Schlüsselspeicher verwenden.The SQL Server Management Studio or any other tool can't be used to create column encryption keys using column master keys in the Java Key Store. Die Client Anwendung muss den Spalten Verschlüsselungsschlüssel Programm gesteuert mithilfe der sqlservercolumnencryptionjavakeystoreprovider-Klasse erstellen.The client application must create the column encryption key programmatically using the SQLServerColumnEncryptionJavaKeyStoreProvider class. Weitere Informationen finden Sie unter mithilfe von Hauptschlüssel-Speicheranbieter für die programmgesteuerte schlüsselbereitstellung.For more information, see Using column master key store providers for programmatic key provisioning.

Implementieren eines benutzerdefinierten Speicheranbieters für den SpaltenhauptschlüsselImplementing a custom column master key store provider

Wenn Sie Spaltenhauptschlüssel in einem Schlüsselspeicher speichern möchten, der nicht von einem vorhandenen Anbieter unterstützt wird, können Sie einen benutzerdefinierten Anbieter implementieren, indem Sie die SQLServerColumnEncryptionKeyStoreProvider-Klasse erweitern und den Anbieter mithilfe der SQLServerConnection.registerColumnEncryptionKeyStoreProviders()-Methode registrieren.If you want to store column master keys in a keystore that is not supported by an existing provider, you can implement a custom provider by extending the SQLServerColumnEncryptionKeyStoreProvider Class and registering the provider using the SQLServerConnection.registerColumnEncryptionKeyStoreProviders() method.

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

Registrieren Sie den Anbieter:Register the provider:

SQLServerColumnEncryptionKeyStoreProvider storeProvider = new MyCustomKeyStore();
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(storeProvider.getName(), storeProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);

Verwenden von Spaltenhauptschlüssel-Speicheranbietern für die programmgesteuerte SchlüsselbereitstellungUsing column master key store providers for programmatic key provisioning

Beim Zugriff auf verschlüsselte Spalten sucht der Microsoft JDBC-Treiber für SQL Server den richtigen Speicheranbieter für Spaltenhauptschlüssel transparent und ruft ihn anschließend auf, um die Spaltenverschlüsselungsschlüssel zu entschlüsseln.When accessing encrypted columns, the Microsoft JDBC Driver for SQL Server transparently finds and calls the right column master key store provider to decrypt column encryption keys. In der Regel ruft der normale Anwendungscode die Speicheranbieter für Spaltenhauptschlüssel nicht direkt auf.Typically, your normal application code doesn't directly call column master key store providers. Sie können einen Anbieter jedoch Programm gesteuert instanziieren und abrufen, um Always Encrypted Schlüssel bereitzustellen und zu verwalten.You may, however, instantiate and call a provider programmatically to provision and manage Always Encrypted keys. Dieser Schritt kann ausgeführt werden, um einen verschlüsselten Spalten Verschlüsselungsschlüssel zu generieren und einen Spalten Verschlüsselungsschlüssel als Teil Spalten-Hauptschlüssel Rotation zu entschlüsseln, z. b..This step may be done to generate an encrypted column encryption key and decrypt a column encryption key as part column master key rotation, for example. Weitere Informationen finden Sie unter Overview of Key Management for Always Encrypted(Übersicht über die Schlüsselverwaltung für Always Encrypted).For more information, see Overview of Key Management for Always Encrypted.

Die Implementierung Ihrer eigenen Schlüsselverwaltungstools ist möglicherweise erforderlich, wenn Sie einen benutzerdefinierten Schlüsselspeicheranbieter verwenden.If you use a custom keystore provider, implementing your own key management tools may be required. Wenn Sie Schlüssel verwenden, die im Windows-Zertifikat Speicher oder in Azure Key Vault gespeichert sind, können Sie vorhandene Tools wie SQL Server Management Studio oder PowerShell verwenden, um Schlüssel zu verwalten und bereitzustellen.When using keys stored in Windows Certificate Store or in Azure Key Vault, you can use existing tools, such as SQL Server Management Studio or PowerShell, to manage and provision keys. Wenn Sie Schlüssel verwenden, die im Java-Schlüsselspeicher gespeichert sind, müssen Sie Schlüsselprogramm gesteuert bereitstellen.When using keys stored in the Java Key Store, you need to provision keys programmatically. Das folgende Beispiel veranschaulicht die Verwendung der sqlservercolumnencryptionjavakeystoreprovider-Klasse, um den Schlüssel mit einem Schlüssel zu verschlüsseln, der im Java-Schlüsselspeicher gespeichert ist.The following example illustrates using the SQLServerColumnEncryptionJavaKeyStoreProvider class to encrypt the key with a key stored in the Java Key Store.

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 = "********".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>;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://docs.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();
    }
}

Aktivieren von Always Encrypted für AnwendungsabfragenEnabling Always Encrypted for application queries

Die einfachste Möglichkeit zum Aktivieren der Verschlüsselung von Parametern und der Entschlüsselung von Abfrageergebnissen, die auf verschlüsselte Spalten ausgerichtet sind, besteht im Festlegen des Werts für das Kennwort der columnEncryptionSetting-Verbindungszeichenfolge auf Enabled.The easiest way to enable the encryption of parameters and the decryption of query results that target encrypted columns is by setting the value of the columnEncryptionSetting connection string keyword to Enabled.

Die folgende Verbindungs Zeichenfolge ist ein Beispiel für das Aktivieren von Always Encrypted im JDBC-Treiber:The following connection string is an example of enabling Always Encrypted in the JDBC driver:

String connectionUrl = "jdbc:sqlserver://<server>:<port>;user=<user>;password=<password>;databaseName=<database>;columnEncryptionSetting=Enabled;";
SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);

Der folgende Code ist ein entsprechendes Beispiel, in dem das SQLServerDataSource-Objekt verwendet wird:The following code is an equivalent example using the 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 kann auch für einzelne Abfragen aktiviert werden.Always Encrypted can also be enabled for individual queries. Weitere Informationen finden Sie weiter unten im Abschnitt Kontrollieren der Auswirkungen von Always Encrypted auf die Leistung.For more information, see Controlling the performance impact of Always Encrypted. Die Aktivierung von Always Encrypted ist für eine erfolgreiche Verschlüsselung und Entschlüsselung nicht ausreichend.Enabling Always Encrypted isn't sufficient for encryption or decryption to succeed. Sie müssen auch Folgendes sicherstellen:You also need to make sure:

  • Die Anwendung verfügt über die Datenbankberechtigungen VIEW ANY COLUMN MASTER KEY DEFINITION und VIEW ANY COLUMN ENCRYPTION KEY DEFINITION , die für den Zugriff auf die Metadaten in der Datenbank über Always Encrypted-Schlüssel erforderlich sind.The application has the VIEW ANY COLUMN MASTER KEY DEFINITION and VIEW ANY COLUMN ENCRYPTION KEY DEFINITION database permissions, required to access the metadata about Always Encrypted keys in the database. Weitere Informationen finden Sie unter Berechtigungen in Always Encrypted (Datenbank-Engine).For details, see Permissions in Always Encrypted (Database Engine).
  • Die Anwendung kann auf den Hauptschlüssel der Spalte zugreifen, der die Spaltenverschlüsselungsschlüssel schützt, mit denen die abgefragten Datenbankspalten verschlüsselt werden.The application can access the column master key that protects the column encryption keys, which encrypt the queried database columns. Wenn Sie den Java-Schlüsselspeicher Anbieter verwenden möchten, müssen Sie zusätzliche Anmelde Informationen in der Verbindungs Zeichenfolge angeben.To use the Java Key Store provider, you need to provide additional credentials in the connection string. Weitere Informationen finden Sie unter Verwenden des Java-Schlüsselspeicher Anbieters.For more information, see Using Java Key Store provider.

Konfigurieren der Art und Weise, wie java.sql.Time-Werte an den Server gesendet werdenConfiguring how java.sql.Time values are sent to the server

Die sendTimeAsDatetime-Verbindungseigenschaft wird dazu verwendet, die Art und Weise zu konfigurieren, auf die der java.sql.Time-Wert an den Server gesendet wird.The sendTimeAsDatetime connection property is used to configure how the java.sql.Time value is sent to the server. Wenn der Wert auf false festgelegt ist, wird der Zeitwert als SQL Server time-Typ gesendet.When set to false, the time value is sent as a SQL Server time type. Wenn der Wert auf true festgelegt ist, wird der Zeitwert als DateTime-Typ gesendet.When set to true, the time value is sent as a datetime type. Wenn eine Zeitspalte verschlüsselt ist, muss die sendtimeasdatetime -Eigenschaft den Wert false aufweisen, da verschlüsselte Spalten die Konvertierung von Time in DateTime nicht unterstützen.If a time column is encrypted, the sendTimeAsDatetime property must be false, as encrypted columns don't support the conversion from time to datetime. Beachten Sie auch, dass diese Eigenschaft standardmäßig "true" ist. Wenn Sie also verschlüsselte Zeit Spalten verwenden, müssen Sie diese Eigenschaft auf "false" festlegen.Also note that this property is by default true, so when using encrypted time columns you'll have to set it to false. Andernfalls löst der Treiber eine Ausnahme aus.Otherwise, the driver will throw an exception. Ab Version 6,0 des Treibers verfügt die SQLServerConnection-Klasse über zwei Methoden, um den Wert dieser Eigenschaft Programm gesteuert zu konfigurieren:Starting with version 6.0 of the driver, the SQLServerConnection class has two methods to configure the value of this property programmatically:

  • public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
  • öffentlicher boolescher Wert getSendTimeAsDatetime()public boolean getSendTimeAsDatetime()

Weitere Informationen zu dieser Eigenschaft finden Sie unter Konfigurieren der Art und Weise, wie java.sql.Time-Werte an den Server gesendet werden.For more information on this property, see Configuring How java.sql.Time Values are Sent to the Server.

Konfigurieren, wie Zeichen folgen Werte an den Server gesendet werdenConfiguring how String values are sent to the server

Die sendStringParametersAsUnicode -Verbindungs Eigenschaft wird verwendet, um zu konfigurieren, wie Zeichen folgen Werte an SQL Server gesendet werden.The sendStringParametersAsUnicode connection property is used to configure how String values are sent to SQL Server. Wenn die Eigenschaft auf „TRUE“ festgelegt ist, werden String-Parameter im Unicode-Format an den Server gesendet.If set to true, String parameters are sent to the server in Unicode format. Wenn der Wert auf false festgelegt ist, werden Zeichen folgen Parameter im nicht-Unicode-Format, z. b. ASCII oder MBCS, anstelle von Unicode gesendet.If set to false, String parameters are sent in non-Unicode format, such as ASCII or MBCS, instead of Unicode. Der Standardwert dieser Eigenschaft ist „TRUE“.The default value for this property is true. Wenn Always Encrypted aktiviert ist und eine char/varchar/varchar (max)-Spalte verschlüsselt ist, muss der Wert von sendStringParametersAsUnicode auf false festgelegt werden.When Always Encrypted is enabled and a char/varchar/varchar(max) column is encrypted, the value of sendStringParametersAsUnicode must be set to false. Wenn diese Eigenschaft auf true festgelegt ist, löst der Treiber eine Ausnahme aus, wenn Daten aus einer verschlüsselten char/varchar/varchar (max)-Spalte mit Unicode-Zeichen entschlüsselt werden.If this property is set to true, the driver will throw an exception when decrypting data from an encrypted char/varchar/varchar(max) column that has Unicode characters. Weitere Informationen zu dieser Eigenschaft finden Sie unter Festlegen der Verbindungs Eigenschaften.For more information on this property, see Setting the Connection Properties.

Abrufen und Ändern von Daten in verschlüsselten SpaltenRetrieving and modifying data in encrypted columns

Nachdem Sie Always Encrypted für Anwendungs Abfragen aktiviert haben, können Sie JDBC-Standard-APIs verwenden, um Daten in verschlüsselten Daten Bank Spalten abzurufen oder zu ändern.Once you enable Always Encrypted for application queries, you can use standard JDBC APIs to retrieve or modify data in encrypted database columns. Wenn Ihre Anwendung über die erforderlichen Daten Bank Berechtigungen verfügt und auf den Spalten Hauptschlüssel zugreifen kann, verschlüsselt der Treiber alle Abfrage Parameter, die auf verschlüsselte Spalten ausgerichtet sind, und entschlüsselt Daten, die aus verschlüsselten Spalten abgerufen werden.If your application has the required database permissions and can access the column master key, the driver will encrypt any query parameters that target encrypted columns and will decrypt data that is retrieved from encrypted columns.

Wenn Always Encrypted nicht aktiviert ist, tritt bei Abfragen mit Parametern, die verschlüsselte Spalten anzielen, ein Fehler auf.If Always Encrypted isn't enabled, queries with parameters that target encrypted columns will fail. Abfragen können weiterhin Daten aus verschlüsselten Spalten abrufen, solange die Abfrage keine Parameter für verschlüsselte Spalten enthält.Queries can still retrieve data from encrypted columns as long as the query has no parameters targeting encrypted columns. Der Treiber versucht jedoch nicht, die aus verschlüsselten Spalten abgerufenen Werte zu entschlüsseln, deshalb erhält die Anwendung binär verschlüsselte Daten (als Bytearrays).However, the driver won't attempt to decrypt any values retrieved from encrypted columns and the application will receive binary encrypted data (as byte arrays).

In der folgenden Tabelle wird das Verhalten von Abfragen in Abhängigkeit davon zusammengefasst, ob Always Encrypted aktiviert ist:The following table summarizes the behavior of queries depending on whether Always Encrypted is enabled or not:

AbfragemerkmalQuery characteristic Always Encrypted ist aktiviert und die Anwendung kann auf die Schlüssel und Schlüsselmetadaten zugreifen.Always Encrypted is enabled and application can access the keys and key metadata Always Encrypted ist aktiviert, und die Anwendung kann nicht auf die Schlüssel oder Schlüsselmetadaten zugreifen.Always Encrypted is enabled and application can't access the keys or key metadata Always Encrypted ist deaktiviertAlways Encrypted is disabled
Abfragen mit Parametern, die auf verschlüsselte Spalten ausgerichtet sind.Queries with parameters targeting encrypted columns. Parameterwerte werden transparent verschlüsselt.Parameter values are transparently encrypted. FehlerError FehlerError
Abfragen, bei denen Daten von verschlüsselten Spalten ohne Parameter abgerufen werden, die auf verschlüsselte Spalten ausgerichtet sind.Queries retrieving data from encrypted columns without parameters targeting encrypted columns. Ergebnisse von verschlüsselten Spalten werden transparent entschlüsselt.Results from encrypted columns are transparently decrypted. Die Anwendung erhält Klartextwerte der JDBC-Datentypen, die den SQL Server-Datentypen entsprechen, die für die verschlüsselten Spalten konfiguriert wurden.The application receives plaintext values of the JDBC datatypes corresponding to the SQL Server types configured for the encrypted columns. FehlerError Ergebnisse von verschlüsselten Spalten werden nicht entschlüsselt.Results from encrypted columns aren't decrypted. Die Anwendung erhält verschlüsselte Werte als Bytearrays (byte[]).The application receives encrypted values as byte arrays (byte[]).

Einfügen und Abrufen von verschlüsselten Daten BeispielenInserting and retrieving encrypted data examples

Die folgenden Beispiele veranschaulichen das Abrufen und Ändern von Daten in verschlüsselten Spalten.The following examples illustrate retrieving and modifying data in encrypted columns. In den Beispielen wird davon ausgegangen, dass die Ziel Tabelle das folgende Schema und die verschlüsselten Spalten SSN und BirthDate hat.The examples assume the target table with the following schema and encrypted SSN and BirthDate columns. Wenn Sie einen Spalten Hauptschlüssel mit dem Namen "mycmk" und einen Spalten Verschlüsselungsschlüssel mit dem Namen "mycek" konfiguriert haben (wie in den vorherigen Abschnitten für Keystore-Anbieter beschrieben), können Sie die Tabelle mit diesem Skript erstellen:If you've configured a Column Master Key named "MyCMK" and a Column Encryption Key named "MyCEK" (as described in the preceding keystore providers sections), you can create the table using this 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

Für jedes Java-Codebeispiel müssen Sie Keystore-spezifischen Code an der angegebenen Position einfügen.For each Java code example, you'll need to insert keystore-specific code in the location noted.

Wenn Sie einen Azure Key Vault Keystore-Anbieter verwenden:If you're using an Azure Key Vault keystore provider:

    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>;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";

Wenn Sie einen Keystore-Anbieter für den Windows-Zertifikat Speicher verwenden:If you're using a Windows Certificate Store keystore provider:

    String connectionUrl = "jdbc:sqlserver://<server>:<port>;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";

Wenn Sie einen Schlüsselspeicher Anbieter für den Java-Schlüsselspeicher verwenden:If you're using a Java Key Store keystore provider:

    String connectionUrl = "jdbc:sqlserver://<server>:<port>;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=<path to jks or pfx file>;keyStoreSecret=<keystore secret/password>";

Beispiel zum Einfügen von DatenInserting data example

In diesem Beispiel wird eine Zeile in die Tabelle „Patients“ eingefügt.This example inserts a row into the Patients table. Beachten Sie Folgendes:Note the following items:

  • Es erfolgt keine spezielle Verschlüsselung im Beispielcode.There's nothing specific to encryption in the sample code. Der Microsoft JDBC-Treiber für SQL Server erkennt und verschlüsselt automatisch die Parameter, die auf verschlüsselte Spalten ausgerichtet sind.The Microsoft JDBC Driver for SQL Server automatically detects and encrypts the parameters that target encrypted columns. Durch dieses Verhalten wird die Verschlüsselung für die Anwendung transparent.This behavior makes encryption transparent to the application.
  • Die in Daten Bank Spalten eingefügten Werte, einschließlich der verschlüsselten Spalten, werden mithilfe von SQLServerPreparedStatement als Parameter weitergegeben.The values inserted into database columns, including the encrypted columns, are passed as parameters using SQLServerPreparedStatement. Während die Verwendung von Parametern optional ist, wenn Werte an nicht verschlüsselte Spalten gesendet werden (obwohl es dringend empfohlen wird, da es dabei hilft, eine Einschleusung von SQL-Befehlen zu verhindern), ist sie für Werte erforderlich, die verschlüsselte Spalten anzielen.While using parameters is optional when sending values to non-encrypted columns (although, it's highly recommended because it helps prevent SQL injection), it's required for values that target encrypted columns. Wenn die in die verschlüsselten Spalten eingefügten Werte als Literale, die in die Abfrage Anweisung eingebettet sind, übertragen wurden, konnte die Abfrage nicht ausgeführt werden, da der Treiber nicht in der Lage wäre, die Werte in den verschlüsselten Ziel Spalten zu ermitteln und die Werte nicht zu verschlüsseln.If the values inserted into the encrypted columns were passed as literals embedded in the query statement, the query would fail because the driver wouldn't be able to determine the values in the target encrypted columns and it wouldn't encrypt the values. Daher würde der Server sie zurückweisen, da sie mit den verschlüsselten Spalten inkompatibel sind.As a result, the server would reject them as incompatible with the encrypted columns.
  • Alle Werte werden vom Programm als Klartext ausgegeben, da der JDBC-Treiber für SQL Server die aus den verschlüsselten Spalten abgerufenen Daten transparent entschlüsselt.All values printed by the program will be in plaintext, as the Microsoft JDBC Driver for SQL Server will transparently decrypt the data retrieved from the encrypted columns.
  • Wenn Sie eine Suche mit einer WHERE-Klausel durchgeführt haben, muss der in der WHERE-Klausel verwendete Wert als Parameter übergeben werden, damit der Treiber ihn vor dem Senden an die Datenbank transparent verschlüsseln kann.If you're doing a lookup using a WHERE clause, the value used in the WHERE clause needs to be passed as a parameter so that the driver can transparently encrypt it before sending it to the database. Im folgenden Beispiel wird die SSN als Parameter übergeben, der LastName wird jedoch als Literalwert übergeben, da LastName nicht verschlüsselt ist.In the following example, the SSN is passed as a parameter but the LastName is passed as a literal as LastName isn't encrypted.
  • Die Setter-Methode, die für den Parameter verwendet wird, der die ssn-Spalte als Ziel verwendet, ist SetString (), der dem Datentyp char/varchar SQL Server zugeordnet wird.The setter method used for the parameter targeting the SSN column is setString(), which maps to the char/varchar SQL Server data type. Wenn für diesen Parameter die setNString()-Methode verwendet wurde, die „nchar“ bzw. „nvarchar“ zugeordnet wird, würde bei der Abfrage ein Fehler auftreten, da Always Encrypted keine Konvertierungen von verschlüsselten nchar- und nvarchar-Werten in verschlüsselte char- und varchar-Werte unterstützt.If, for this parameter, the setter method used was setNString(), which maps to nchar/nvarchar, the query would fail, as Always Encrypted doesn't support conversions from encrypted nchar/nvarchar values to encrypted char/varchar values.
// <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();
}

Beispiel zum Abrufen von KlartextdatenRetrieving plaintext data example

Im folgenden Beispiel wird das Filtern von Daten auf Basis verschlüsselter Werte und das Abrufen von Klartextdaten aus verschlüsselten Spalten veranschaulicht.The following example demonstrates filtering data based on encrypted values and retrieving plaintext data from encrypted columns. Beachten Sie Folgendes:Note the following items:

  • Der in der WHERE-Klausel zum Filtern der Spalte „SSN“ verwendete Wert muss als Parameter übergeben werden, damit ihn der Microsoft JDBC-Treiber für SQL Server vor dem Senden an die Datenbank transparent verschlüsseln kann.The value used in the WHERE clause to filter on the SSN column needs to be passed as a parameter so that the Microsoft JDBC Driver for SQL Server can transparently encrypt it before sending it to the database.
  • Alle Werte werden vom Programm als Klartext ausgegeben, da der JDBC-Treiber für SQL Server die aus den Spalten „SSN“ und „BirthDate“ abgerufenen Daten transparent entschlüsselt.All values printed by the program will be in plaintext, as the Microsoft JDBC Driver for SQL Server will transparently decrypt the data retrieved from the SSN and BirthDate columns.

Hinweis

Abfragen können für Spalten Übereinstimmungsvergleiche ausführen, wenn diese mittels deterministischer Verschlüsselung verschlüsselt sind.if columns are encrypted using deterministic encryption, queries can perform equality comparisons on them. Weitere Informationen finden Sie unter Auswählen der deterministischen oder zufälligen Verschlüsselung in Always Encrypted (Datenbank-Engine).For more information, see Selecting Deterministic or Randomized encryption in Always Encrypted (Database Engine).

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

Beispiel zum Abrufen von verschlüsselten DatenRetrieving encrypted data example

Wenn Always Encrypted nicht aktiviert ist, können Abfragen weiterhin Daten aus verschlüsselten Spalten abrufen, so lange die Abfrage keine Parameter für verschlüsselte Spalten enthält.If Always Encrypted isn't enabled, a query can still retrieve data from encrypted columns, as long as the query has no parameters targeting encrypted columns.

In den folgenden Beispielen wird das Abrufen von binär verschlüsselten Daten aus verschlüsselten Spalten veranschaulicht.The following example illustrates retrieving binary encrypted data from encrypted columns. Beachten Sie Folgendes:Note the following items:

  • Da Always Encrypted in der Verbindungszeichenfolge nicht aktiviert ist, gibt die Abfrage verschlüsselte Werte von „SSN“ und „BirthDate“ als Bytearrays zurück (das Programm konvertiert die Werte in Zeichenfolgen).Since Always Encrypted isn't enabled in the connection string, the query will return encrypted values of SSN and BirthDate as byte arrays (the program converts the values to strings).
  • Eine Abfrage, die Daten aus verschlüsselten Spalten mit deaktiviertem Always Encrypted abruft, kann Parameter aufweisen, so lange keiner der Parameter auf eine verschlüsselte Spalte ausgerichtet ist.A query retrieving data from encrypted columns with Always Encrypted disabled can have parameters, as long as none of the parameters target an encrypted column. In der folgenden Abfrage wird nach der Spalte „LastName“ gefiltert, die in der Datenbank nicht verschlüsselt ist.The following query filters by LastName, which isn't encrypted in the database. Wenn die Abfrage nach „SSN“ oder „BirthDate“ filtert, würde ein Fehler auftreten.If the query filtered by SSN or BirthDate, the query would fail.
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();
}

Vermeiden allgemeiner Probleme beim Abfragen von verschlüsselten SpaltenAvoiding common problems when querying encrypted columns

Dieser Abschnitt beschreibt die allgemeinen Kategorien von Fehlern bei der Abfrage verschlüsselter Spalten über Java-Anwendungen sowie einige Grundsätze zum Vermeiden dieser Fehler.This section describes common categories of errors when querying encrypted columns from Java applications and a few guidelines on how to avoid them.

Konvertierungsfehler durch nicht unterstützte DatentypenUnsupported data type conversion errors

Always Encrypted unterstützt einige Konvertierungen für verschlüsselte Datentypen.Always Encrypted supports few conversions for encrypted data types. Eine ausführliche Liste der unterstützten Typkonvertierungen finden Sie unter Always Encrypted (Datenbank-Engine).See Always Encrypted (Database Engine) for the detailed list of supported type conversions. Auf folgende Weise können Sie Fehler bei der Datentypkonvertierung vermeiden:Here is what you can do to avoid data type conversion errors. Stellen Sie Folgendes sicher:Make sure that:

  • beim Übergeben von Werten für Parameter, die auf verschlüsselte Spalten abzielen, verwenden Sie die richtigen Setter-Methoden.you use the proper setter methods when passing values for parameters that target encrypted columns. Stellen Sie sicher, dass der SQL Server-Datentyp des Parameters exakt dem Typ der Ziel Spalte entspricht, oder dass eine Konvertierung des SQL Server Datentyps des Parameters in den Zieltyp der Spalte unterstützt wird.Ensure that the SQL Server data type of the parameter is exactly the same as the type of the target column or a conversion of the SQL Server data type of the parameter to the target type of the column is supported. API-Methoden wurden den Klassen SQLServerPreparedStatement, SQLServerCallableStatement und SQLServerResultSet hinzugefügt, um Parameter zu übergeben, die bestimmten SQL Server Datentypen entsprechen.API methods have been added to the SQLServerPreparedStatement, SQLServerCallableStatement, and SQLServerResultSet classes to pass parameters corresponding to specific SQL Server data types. Wenn eine Spalte z. b. nicht verschlüsselt ist, können Sie die setTimestamp ()-Methode verwenden, um einen Parameter an eine datetime2-oder eine datetime-Spalte zu übergeben.For example, if a column isn't encrypted you can use the setTimestamp() method to pass a parameter to a datetime2 or to a datetime column. Wenn eine Spalte jedoch verschlüsselt ist, müssen Sie die exakte Methode verwenden, die den Typ der Spalte in der Datenbank darstellt.But when a column is encrypted you'll have to use the exact method representing the type of the column in the database. Verwenden Sie z. b. setTimestamp (), um Werte an eine verschlüsselte datetime2-Spalte zu übergeben, und verwenden Sie SetDateTime (), um Werte an eine verschlüsselte datetime-Spalte zu übergeben.For example, use setTimestamp() to pass values to an encrypted datetime2 column and use setDateTime() to pass values to an encrypted datetime column. Eine komplette Liste der neuen APIs finden Sie unter Always Encrypted-API-Referenz für den JDBC-Treiber .See Always Encrypted API Reference for the JDBC Driver for a complete list of new APIs.
  • Die Genauigkeit und Dezimalstellenanzahl von Parametern, die auf Spalten der SQL Server-Datentypen „decimal“ und „numeric“ ausgerichtet sind, ist mit der für die Zielspalte konfigurierten Genauigkeit und Dezimalstellenanzahl identisch.the precision and scale of parameters targeting columns of the decimal and numeric SQL Server data types is the same as the precision and scale configured for the target column. API-Methoden wurden den Klassen SQLServerPreparedStatement, SQLServerCallableStatement und SQLServerResultSet hinzugefügt, um Genauigkeit und Skalierung zusammen mit Datenwerten für Parameter/Spalten zu akzeptieren, die die Datentypen decimal und numeric darstellen.API methods have been added to the SQLServerPreparedStatement, SQLServerCallableStatement, and SQLServerResultSet classes to accept precision and scale along with data values for parameters/columns representing decimal and numeric data types. Eine komplette Liste neuer/überladener APIs finden Sie unter Always Encrypted-API-Referenz für den JDBC-Treiber .See Always Encrypted API Reference for the JDBC Driver for a complete list of new/overloaded APIs.
  • die Genauigkeit/Dezimalstellen Genauigkeit/Dezimalstellen von Parametern, die auf Spalten der datetime2-, DateTimeOffset-oder Time-SQL Server Datentypen abzielen, ist nicht größer als die Genauigkeit/Dezimalstellen Genauigkeit/Dezimalstellen für die Ziel Spalte in Abfragen, die Werte der Ziel Spalte ändern.the fractional seconds precision/scale of parameters targeting columns of datetime2, datetimeoffset, or time SQL Server data types isn't greater than the fractional seconds precision/scale for the target column in queries that modify values of the target column. API-Methoden wurden den Klassen SQLServerPreparedStatement, SQLServerCallableStatement und SQLServerResultSet hinzugefügt, um Genauigkeit und Dezimalstellen für Sekundenbruchteile zusammen mit Datenwerten für Parameter zu akzeptieren, die diese Datentypen darstellen.API methods have been added to the SQLServerPreparedStatement, SQLServerCallableStatement, and SQLServerResultSet classes to accept fractional seconds precision/scale along with data values for parameters representing these data types. Eine umfassende Liste neuer/überladener APIs finden Sie unter Always Encrypted-API-Referenz für den JDBC-Treiber.For a complete list of new/overloaded APIs, see Always Encrypted API Reference for the JDBC Driver.

Fehler aufgrund falscher Verbindungs EigenschaftenErrors due to incorrect connection properties

In diesem Abschnitt wird beschrieben, wie Verbindungseinstellungen ordnungsgemäß konfiguriert werden, um Always Encrypted Daten zu verwenden.This section describes how to configure connection settings properly to use Always Encrypted data. Da verschlüsselte Datentypen Eingeschränkte Konvertierungen unterstützen, müssen die Verbindungseinstellungen sendtimeasdatetime und sendStringParametersAsUnicode ordnungsgemäß konfiguriert werden, wenn verschlüsselte Spalten verwendet werden.Since encrypted data types support limited conversions, the sendTimeAsDatetime and sendStringParametersAsUnicode connection settings need proper configuration when using encrypted columns. Stellen Sie Folgendes sicher:Make sure that:

Fehler aufgrund der Übergabe von Klartext anstelle von verschlüsselten WertenErrors due to passing plaintext instead of encrypted values

Jeder Wert, der auf eine verschlüsselte Spalte ausgerichtet ist, muss in der Anwendung verschlüsselt werden.Any value that targets an encrypted column needs to be encrypted inside the application. Ein Versuch, einen Klartextwert einzufügen bzw. zu ändern oder nach einem Klartextwert für eine verschlüsselte Spalte zu filtern, führt zu einem Fehler wie dem folgenden:An attempt to insert/modify or to filter by a plaintext value on an encrypted column will result in an error similar to this one:

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'

Stellen Sie Folgendes sicher, um solche Fehler zu vermeiden:To prevent such errors, make sure:

  • Always Encrypted ist für Anwendungsabfragen aktiviert, die auf verschlüsselte Spalten ausgerichtet sind (für die Verbindungszeichenfolge oder für eine bestimmte Abfrage).Always Encrypted is enabled for application queries targeting encrypted columns (for the connection string or for a specific query).
  • Sie verwenden vorbereitete Anweisungen und Parameter, um Daten zu senden, die auf verschlüsselte Spalten ausgerichtet sind.you use prepared statements and parameters to send data targeting encrypted columns. Das folgende Beispiel zeigt eine Abfrage, die falsch nach einem Literal bzw. einer Konstante einer verschlüsselten Spalte (SSN) filtert, anstatt das Literal innerhalb eines Parameters zu übergeben.The following example shows a query that incorrectly filters by a literal/constant on an encrypted column (SSN), instead of passing the literal inside as a parameter. Diese Abfrage kann nicht ausgeführt werden:This query will fail:
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM Customers WHERE SSN='795-73-9838'");

Erzwingen der Verschlüsselung von Eingabe ParameternForce encryption on input parameters

Die Funktion "Verschlüsselung erzwingen" erzwingt die Verschlüsselung eines Parameters bei Verwendung Always encrypted.The Force Encryption feature enforces encryption of a parameter when using Always Encrypted. Wenn das Erzwingen der Verschlüsselung verwendet wird und SQL Server den Treiber informiert, dass der Parameter nicht verschlüsselt werden muss, tritt bei der Abfrage, die diesen Parameter verwendet, ein Fehler auf.If force encryption is used and SQL Server informs the driver that the parameter doesn't need to be encrypted, the query using the parameter will fail. Diese Eigenschaft bietet zusätzlichen Schutz vor Angriffen, bei denen ein kompromittierter SQL Server falsche Verschlüsselungsmetadaten für den Client bereitstellt, was zur Offenlegung von Daten führen kann.This property provides additional protection against security attacks that involve a compromised SQL Server providing incorrect encryption metadata to the client, which may lead to data disclosure. Die Set *-Methoden in der SQLServerPreparedStatement-Klasse und der SQLServerCallableStatement-Klasse sowie die Update*-Methoden in der SQLServerResultSet-Klasse sind überladen, um ein boolesches Argument zum Angeben der Einstellung "Verschlüsselung erzwingen" zu akzeptieren.The set* methods in the SQLServerPreparedStatement and SQLServerCallableStatement classes and the update* methods in the SQLServerResultSet class are overloaded to accept a boolean argument to specify the force encryption setting. Wenn der Wert dieses Arguments false ist, wird die Verschlüsselung von Parametern vom Treiber nicht erzwungen.If the value of this argument is false, the driver won't force encryption on parameters. Wenn die Option Verschlüsselung erzwingen auf true festgelegt ist, wird der Abfrage Parameter nur gesendet, wenn die Ziel Spalte verschlüsselt ist und Always Encrypted für die Verbindung oder für die-Anweisung aktiviert ist.If force encryption is set to true, the query parameter is only sent if the destination column is encrypted and Always Encrypted is enabled on the connection or on the statement. Die Verwendung dieser Eigenschaft bietet eine zusätzliche Sicherheitsebene, die sicherstellt, dass der Treiber nicht versehentlich Daten an SQL Server als Klartext sendet, wenn die Verschlüsselung erwartet wird.Using this property gives an extra layer of security, ensuring that the driver doesn't mistakenly send data to SQL Server as plaintext when it's expected to be encrypted.

Weitere Informationen zu den Methoden SQLServerPreparedStatement und SQLServerCallableStatement, die mit der Einstellung Verschlüsselung erzwingen überladen werden, finden Sie unter Always Encrypted-API-Referenz für den JDBC-Treiber .For more information on the SQLServerPreparedStatement and SQLServerCallableStatement methods that are overloaded with the force encryption setting, see Always Encrypted API Reference for the JDBC Driver

Kontrollieren der Auswirkungen von Always Encrypted auf die LeistungControlling the performance impact of Always Encrypted

Da Always Encrypted eine clientseitige Verschlüsselungstechnologie ist, werden die meisten Leistungseinbußen auf der Clientseite und nicht in der Datenbank beobachtet.Because Always Encrypted is a client-side encryption technology, most of the performance overhead is observed on the client side, not in the database. Neben den Kosten für Verschlüsselungs- und Entschlüsselungsvorgänge ergeben sich folgende andere Quellen für Leistungseinbußen auf der Clientseite:Apart from the cost of encryption and decryption operations, other sources of performance overheads on the client side are:

  • Zusätzliche Roundtrips zur Datenbank zum Abrufen von Metadaten für Abfrageparameter.Additional round trips to the database to retrieve metadata for query parameters.
  • Aufrufe an einen Spaltenhauptschlüsselspeicher für den Zugriff auf einen Spaltenhauptschlüssel.Calls to a column master key store to access a column master key.

In diesem Abschnitt werden die integrierten Leistungsoptimierungen JDBC-Treiber für SQL Server und die Steuerung der Auswirkungen der beiden oben genannten Faktoren auf die Leistung beschrieben.This section describes the built-in performance optimizations in the Microsoft JDBC Driver for SQL Server and how you can control the impact of the above two factors on performance.

Kontrollieren von Roundtrips zum Abrufen von Metadaten für AbfrageparameterControlling round trips to retrieve metadata for query parameters

Wenn Always Encrypted für eine Verbindung aktiviert ist, ruft der Treiber standardmäßig sys.sp_describe_parameter_encryption für jede parametrisierte Abfrage auf, wobei die Abfrageanweisung (ohne Parameterwerte) an SQL Server übergeben wird.If Always Encrypted is enabled for a connection, by default the driver will call sys.sp_describe_parameter_encryption for each parameterized query, passing the query statement (without any parameter values) to SQL Server. Die Abfrageanweisung wird vonsys.sp_describe_parameter_encryption analysiert, um zu ermitteln, ob Parameter verschlüsselt werden müssen. In diesem Fall gibt sie die verschlüsselungsbezogenen Informationen zurück, die dem Treiber das Verschlüsseln von Parameterwerten ermöglichen.sys.sp_describe_parameter_encryption analyzes the query statement to find out if any parameters need to be encrypted, and if so, for each one it returns the encryption-related information that will allow the driver to encrypt parameter values. Dieses Verhalten stellt einen hohen Grad an Transparenz für die Clientanwendung sicher.This behavior ensures a high level of transparency to the client application. Solange die Anwendung Parameter verwendet, um Werte, die auf verschlüsselte Spalten ausgerichtet sind, an den Treiber zu übergeben, muss die Anwendung (und der Anwendungsentwickler) nicht wissen, welche Abfragen auf verschlüsselte Spalten zugreifen.As long as the application uses parameters to pass values that target encrypted columns to the driver, the application (and the application developer) doesn't need to know which queries access encrypted columns.

Festlegen von Always Encrypted auf AbfrageebeneSetting Always Encrypted at the query level

Sie können Always Encrypted für einzelne Abfragen aktivieren, anstatt es für die Verbindung einzurichten, um beim Abrufen von Verschlüsselungsmetadaten für parametrisierte Abfragen die Auswirkung auf die Leistung zu steuern.To control the performance impact of retrieving encryption metadata for parameterized queries, you can enable Always Encrypted for individual queries instead of setting it up for the connection. Auf diese Weise können Sie sicherstellen, dass „sys.sp_describe_parameter_encryption“ nur für Abfragen aufgerufen wird, bei denen Ihnen bekannt ist, dass sie über Parameter verfügen, die auf verschlüsselte Spalten ausgerichtet sind.This way you can ensure that sys.sp_describe_parameter_encryption is invoked only for queries that you know have parameters targeting encrypted columns. Beachten Sie jedoch, dass Sie auf diese Weise die Transparenz der Verschlüsselung reduzieren: Wenn Sie die Verschlüsselungseigenschaften der Datenbankspalten ändern, müssen Sie möglicherweise den Code der Anwendung ändern, um ihn mit den Schemaänderungen auszurichten.Note, however, that by doing so you reduce the transparency of encryption: if you change encryption properties of your database columns, you may need to change the code of your application to align it with the schema changes.

Um das Always Encrypted Verhalten einzelner Abfragen zu steuern, müssen Sie einzelne Anweisungs Objekte konfigurieren, indem Sie eine Enum, sqlserverstatuementcolumnencryptionsetting übergeben, die angibt, wie Daten beim Lesen und schreiben gesendet und empfangen werden. verschlüsselte Spalten für diese bestimmte Anweisung.To control the Always Encrypted behavior of individual queries, you need to configure individual statement objects by passing an Enum, SQLServerStatementColumnEncryptionSetting, which specifies how data will be sent and received when reading and writing encrypted columns for that specific statement. Hier sind einige nützliche Richtlinien:Here are some useful guidelines:

  • Wenn für die meisten Abfragen eine Clientanwendung über eine Datenbankverbindung auf verschlüsselte Spalten zugreift, verwenden Sie die folgenden Richtlinien:If most queries a client application sends over a database connection access encrypted columns, use these guidelines:

    • Legen Sie für das Verbindungszeichenfolgen-Kennwort für columnEncryptionSetting den Wert Aktiviertfest.Set the columnEncryptionSetting connection string keyword to Enabled.
    • Legen Sie „SqlCommandColumnEncryptionSetting.Disabled“ für einzelne Abfragen fest, die nicht auf verschlüsselte Spalten zugreifen müssen.Set SQLServerStatementColumnEncryptionSetting.Disabled for individual queries that don't access any encrypted columns. Durch diese Einstellung werden sowohl der Aufruf von „sys.sp_describe_parameter_encryption“ als auch der Versuch deaktiviert, Werte im Resultset zu entschlüsseln.This setting will disable both calling sys.sp_describe_parameter_encryption as well as an attempt to decrypt any values in the result set.
    • Legen Sie „SqlCommandColumnEncryptionSetting.ResultSet“ für einzelne Abfragen fest, die keine Parameter besitzen, für die eine Verschlüsselung erforderlich ist, die aber Daten aus verschlüsselten Spalten abrufen.Set SQLServerStatementColumnEncryptionSetting.ResultSet for individual queries that don't have any parameters requiring encryption but retrieve data from encrypted columns. Durch diese Einstellung werden der Aufruf von „sys.sp_describe_parameter_encryption“ und die Parameterverschlüsselung deaktiviert.This setting will disable calling sys.sp_describe_parameter_encryption and parameter encryption. Die Abfrage ist in der Lage, die Ergebnisse von Spaltenverschlüsselungen zu entschlüsseln.The query will be able to decrypt the results from encryption columns.
  • Wenn für die meisten Abfragen eine Clientanwendung nicht über eine Datenbankverbindung auf verschlüsselte Spalten zugreift, verwenden Sie die folgenden Richtlinien:If most queries a client application sends over a database connection don't access encrypted columns, use these guidelines:

    • Legen Sie für das Verbindungszeichenfolgen-Kennwort für columnEncryptionSetting den Wert Deaktiviertfest.Set the columnEncryptionSetting connection string keyword to Disabled.
    • Legen Sie „SQLServerStatementColumnEncryptionSetting.Enabled“ für einzelne Abfragen mit Parametern fest, die verschlüsselt werden müssen.Set SQLServerStatementColumnEncryptionSetting.Enabled for individual queries that have any parameters that need to be encrypted. Durch diese Einstellung werden sowohl der Aufruf von „sys.sp_describe_parameter_encryption“ als auch die Entschlüsselung von Abfrageergebnissen aktiviert, die aus verschlüsselten Spalten abgerufen werden.This setting will enable both calling sys.sp_describe_parameter_encryption as well as the decryption of any query results retrieved from encrypted columns.
    • Legen Sie „SQLServerStatementColumnEncryptionSetting.ResultSet“ für Abfragen fest, die keine Parameter besitzen, für die eine Verschlüsselung erforderlich ist, die jedoch Daten aus verschlüsselten Spalten abrufen.Set SQLServerStatementColumnEncryptionSetting.ResultSet for queries that don't have any parameters requiring encryption but retrieve data from encrypted columns. Durch diese Einstellung werden der Aufruf von „sys.sp_describe_parameter_encryption“ und die Parameterverschlüsselung deaktiviert.This setting will disable calling sys.sp_describe_parameter_encryption and parameter encryption. Die Abfrage ist in der Lage, die Ergebnisse von Spaltenverschlüsselungen zu entschlüsseln.The query will be able to decrypt the results from encryption columns.

Die sqlserverstatuementcolumnencryptionsetting-Einstellungen können nicht verwendet werden, um die Verschlüsselung zu umgehen und Zugriff auf klar Text Daten zu erhalten.The SQLServerStatementColumnEncryptionSetting settings can't be used to bypass encryption and gain access to plaintext data. Weitere Informationen zum Konfigurieren der Spalten Verschlüsselung für eine-Anweisung finden Sie unter Always Encrypted-API-Referenz für den JDBC-Treiber.For more information on how to configure column encryption on a statement, see Always Encrypted API Reference for the JDBC Driver.

Im folgenden Beispiel ist Always Encrypted für die Datenbankverbindung deaktiviert.In the following example, Always Encrypted is disabled for the database connection. Die von der Anwendung ausgestellte Abfrage weist einen Parameter auf, der die nicht verschlüsselte Spalte „LastName“ anzielt.The query the application issues has a parameter that targets the LastName column that isn't encrypted. Die Abfrage ruft Daten aus den Spalten „SSN“ und „BirthDate“ ab, die beide verschlüsselt sind.The query retrieves data from the SSN and BirthDate columns that are both encrypted. In diesem Fall ist der Aufruf von „sys.sp_describe_parameter_encryption“ nicht erforderlich, um Verschlüsselungsmetadaten abzurufen.In such a case, calling sys.sp_describe_parameter_encryption to retrieve encryption metadata isn't required. Die Entschlüsselung der Abfrageergebnisse muss jedoch aktiviert sein, damit die Anwendung Klartextwerte aus den beiden verschlüsselten Spalten erhalten kann.However, the decryption of the query results needs to be enabled so that the application can receive plaintext values from the two encrypted columns. Mithilfe der sqlserverstatuementcolumnencryptionsetting. Resultset-Einstellung wird sichergestellt, dass.The SQLServerStatementColumnEncryptionSetting.ResultSet setting is used to ensure that.

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

Zwischenspeicherung von SpaltenverschlüsselungsschlüsselnColumn encryption key caching

Der Microsoft JDBC-Treiber für SQL Server speichert die Spaltenverschlüsselungsschlüssel im Klartext im Speicher zwischen, um die Anzahl der Aufrufe an einen Spaltenhauptschlüsselspeicher zu verringern.To reduce the number of calls to a column master key store to decrypt column encryption keys, the Microsoft JDBC Driver for SQL Server caches the plaintext column encryption keys in memory. Nach dem Erhalt des Verschlüsselungsschlüsselwerts für die verschlüsselte Spalte von den Datenbankmetadaten versucht der Treiber zunächst, den Spaltenverschlüsselungsschlüssel im Klartext zu finden, der dem verschlüsselten Schlüsselwert entspricht.After receiving the encrypted column encryption key value from the database metadata, the driver first tries to find the plaintext column encryption key corresponding to the encrypted key value. Der Treiber ruft den Schlüsselspeicher, der den Spaltenhauptschlüssel enthält, nur dann auf, wenn er den verschlüsselten Spaltenverschlüsselungsschlüssel im Cache nicht finden kann.The driver calls the keystore containing the column master key only if it cannot find the encrypted column encryption key value in the cache.

Sie können einen Gültigkeitsdauer Wert für die Spalten Verschlüsselungsschlüssel-Einträge im Cache mithilfe der API setcolumnencryptionkeycachettl () in der SQLServerConnection-Klasse konfigurieren.You can configure a time-to-live value for the column encryption key entries in the cache using the API, setColumnEncryptionKeyCacheTtl(), in the SQLServerConnection class. Der Standardwert für die Gültigkeitsdauer der Spalten Verschlüsselungsschlüssel-Einträge im Cache beträgt zwei Stunden.The default time-to-live value for the column encryption key entries in the cache is two hours. Um das Zwischenspeichern zu deaktivieren, verwenden Sie den Wert 0.To turn off caching, use a value of 0. Verwenden Sie die folgende API, um einen beliebigen Wert für die Gültigkeitsdauer festzulegen:To set any time-to-live value, use the following API:

SQLServerConnection.setColumnEncryptionKeyCacheTtl (int columnEncryptionKeyCacheTTL, TimeUnit unit)

Um beispielsweise einen Wert für die Gültigkeitsdauer von 10 Minuten festzulegen, verwenden Sie Folgendes:For example, to set a time-to-live value of 10 minutes, use:

SQLServerConnection.setColumnEncryptionKeyCacheTtl (10, TimeUnit.MINUTES)

Nur Tage, Stunden, Minuten oder Sekunden werden als Zeiteinheit unterstützt.Only DAYS, HOURS, MINUTES, or SECONDS are supported as the time unit.

Kopieren von verschlüsselten Daten mithilfe von "sqlserverbulkcopy"Copying encrypted data using SQLServerBulkCopy

Mit „SQLServerBulkCopy“ können Sie Daten, die bereits verschlüsselt sind und in einer Tabelle gespeichert werden, in eine andere Tabelle kopieren, ohne die Daten zu entschlüsseln.With SQLServerBulkCopy, you can copy data that is already encrypted and stored in one table to another table without decrypting the data. Gehen Sie dazu wie folgt vor:To do that:

  • Stellen Sie sicher, dass die Verschlüsselungskonfiguration der Zieltabelle mit der Konfiguration der Quelltabelle identisch ist.Make sure the encryption configuration of the target table is identical to the configuration of the source table. Insbesondere müssen für beide Tabellen dieselben Spalten verschlüsselt sein. Zudem müssen die Spalten mithilfe derselben Verschlüsselungstypen und mit denselben Verschlüsselungsschlüsseln verschlüsselt werden.In particular, both tables must have the same columns encrypted and the columns must be encrypted using the same encryption types and the same encryption keys. Wenn eine der Zielspalten anders als die entsprechende Quellspalte verschlüsselt wurde, können Sie die Daten in der Zieltabelle nach dem Kopiervorgang nicht entschlüsseln.If any target column is encrypted differently than its corresponding source column, you won't be able to decrypt the data in the target table after the copy operation. Die Daten werden beschädigt.The data will be corrupted.
  • Konfigurieren Sie beide Datenbankverbindungen, für die Quelltabelle und für die Zieltabelle, ohne Always Encrypted zu aktivieren.Configure both database connections to the source table and to the target table without Always Encrypted enabled.
  • Legen Sie die Option "zubei Zuweisung von Zustellungen" fest.Set the allowEncryptedValueModifications option. Weitere Informationen finden Sie unter Verwenden von Massen kopieren mit dem JDBC-Treiber.For more information, see Using bulk copy with the JDBC driver.

Hinweis

Gehen Sie bei der Angabe von „AllowEncryptedValueModifications“ mit Bedacht vor, da dies möglicherweise zu einer Beschädigung der Datenbank führen kann, da der Microsoft JDBC-Treiber für SQL Server nicht überprüft, ob die Daten tatsächlich verschlüsselt oder mit demselben Verschlüsselungstyp, Algorithmus und Schlüssel wie die Zielspalte ordnungsgemäß verschlüsselt wurden.Use caution when specifying AllowEncryptedValueModifications as this option may lead to corrupting the database because the Microsoft JDBC Driver for SQL Server does not check if the data is indeed encrypted or if it is correctly encrypted using the same encryption type, algorithm, and key as the target column.

Siehe auchSee also

„Immer verschlüsselt“ (Datenbank-Engine)Always Encrypted (Database Engine)