JDBC ドライバーでの Always Encrypted の使用Using Always Encrypted with the JDBC driver

ダウンロードJDBC Driver のダウンロードDownloadDownload JDBC Driver

このページでは、 Always Encryptedと Microsoft JDBC Driver 6.0 (またはそれ以降) を使用して SQL Server の Java アプリケーションを開発する方法について説明します。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 を使用すると、クライアントは SQL Server または Azure SQL データベースにデータまたは暗号化キーを開示することなく、機密データを暗号化することができます。Always Encrypted allows clients to encrypt sensitive data and never reveal the data or the encryption keys to SQL Server or Azure SQL Database. Microsoft JDBC Driver 6.0 for SQL Server 以降など、Always Encrypted が有効のドライバーは、クライアント アプリケーション内の機密データを透過的に暗号化および暗号化解除することで、この動作を実行します。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. ドライバーは、どのクエリパラメーターが Always Encrypted データベースの列に対応しているかを自動的に判断し、それらのパラメーターの値を暗号化して SQL Server または Azure SQL Database に送信します。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. 同様に、ドライバーは、クエリ結果内の暗号化されたデータベース列から取得されたデータを透過的に暗号化解除します。Similarly, the driver transparently decrypts data retrieved from encrypted database columns in query results. 詳細については、JDBC driver のAlways Encrypted (データベースエンジン)Always Encrypted API リファレンスに関する説明を参照してください。For more information, see Always Encrypted (Database Engine) and Always Encrypted API reference for the JDBC driver.

PrerequisitesPrerequisites

  • SQL Server の Microsoft JDBC Driver 6.0 (またはそれ以降) が開発用コンピューターにインストールされていることを確認します。Make sure Microsoft JDBC Driver 6.0 (or higher) for SQL Server is installed on your development machine.

  • Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files (JCE 管轄ポリシーファイル (無制限強度)) をダウンロードしてインストールします。Download and install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. インストール手順、および考えられるエクスポート/インポート問題に関する詳細について、zip ファイルに含まれる Readme を必ず読んでください。Be sure to read the Readme included in the zip file for installation instructions and relevant details on possible export/import issues.

列マスター キー ストアを操作するWorking with column master key stores

暗号化された列のデータを暗号化または暗号化解除するために、SQL Server は列の暗号化キーを保持します。To encrypt or decrypt data for encrypted columns, SQL Server maintains column encryption keys. 列暗号化キーは、データベースのメタデータに暗号化された形式で格納されています。Column encryption keys are stored in encrypted form in the database metadata. 各列暗号化キーには、列暗号化キーの暗号化に使用された対応する列マスター キーが含まれます。Each column encryption key has a corresponding column master key that is used to encrypt the column encryption key. データベースのメタデータには、列のマスターキーが含まれていません。The database metadata doesn't contain the column master keys. これらのキーはクライアントによってのみ保持されます。Those keys are only held by the client. ただし、データベースのメタデータには、クライアントに対して相対的に列マスターキーが格納されている場所に関する情報が含まれます。However the database metadata does contain information about where the column master keys are stored relative to the client. たとえば、データベースのメタデータは、列マスターキーを保持するキーストアが Windows 証明書ストアであり、暗号化と復号化に使用される特定の証明書が Windows 証明書ストア内の特定のパスにあることを示している場合があります。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. クライアントが Windows 証明書ストア内の証明書にアクセスできる場合は、証明書を取得できます。If the client has access to that certificate in the Windows Certificate Store, it can obtain the certificate. その後、証明書を使用して、列暗号化キーの暗号化を解除できます。The certificate can then be used to decrypt the column encryption key. その後、その暗号化キーを使用して、その列暗号化キーを使用する暗号化された列のデータの暗号化解除または暗号化を行うことができます。Then that encryption key can be used to decrypt or encrypt data for encrypted columns that use that column encryption key.

Microsoft JDBC Driver for SQL Server は、 , string, から派生したクラスのインスタンスである列マスターキーストアプロバイダーを使用してキーストアと通信します。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.

組み込み列マスター キー ストア プロバイダーを使用するUsing built-in column master key store providers

Microsoft JDBC Driver for SQL Server には、次の組み込み列マスターキーストアプロバイダーが付属しています。The Microsoft JDBC Driver for SQL Server comes with the following built-in column master key store providers. これらのプロバイダーの一部は、(プロバイダーの検索に使用される) 特定のプロバイダー名に事前登録されています。また、追加の資格情報または明示的な登録が必要なものもあります。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.

クラスClass [説明]Description プロバイダー (検索) 名Provider (lookup) name 事前登録されていますか?Is pre-registered?
SQLServerColumnEncryptionAzureKeyVaultProviderSQLServerColumnEncryptionAzureKeyVaultProvider Azure Key Vault のキーストアのプロバイダー。A provider for a keystore for the Azure Key Vault. AZURE_KEY_VAULTAZURE_KEY_VAULT いいえNo
SQLServerColumnEncryptionCertificateStoreProviderSQLServerColumnEncryptionCertificateStoreProvider Windows 証明書ストアのプロバイダー。A provider for the Windows Certificate Store. MSSQL_CERTIFICATE_STOREMSSQL_CERTIFICATE_STORE はいYes
SQLServerColumnEncryptionJavaKeyStoreProviderSQLServerColumnEncryptionJavaKeyStoreProvider Java キーストアのプロバイダーA provider for the Java keystore MSSQL_JAVA_KEYSTOREMSSQL_JAVA_KEYSTORE はいYes

事前登録されたキーストアプロバイダーの場合、これらのプロバイダーを使用するためにアプリケーションコードを変更する必要はありませんが、次の項目に注意してください。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:

  • ユーザー (またはデータベース管理者) は、列マスター キーのメタデータで構成されているプロバイダー名が正しいこと、および列マスター キー パスが、特定のプロバイダーに対して有効なキー パス形式に準拠していることを確認する必要があります。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. CREATE COLUMN MASTER KEY (Transact-SQL) ステートメントを発行する際に有効なプロバイダー名とキー パスを自動的に生成する、SQL Server Management Studio などのツールを使用してキーを構成することをお勧めします。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.
  • アプリケーションがキー ストア内のキーにアクセスできることを確認します。Ensure your application can access the key in the keystore. このタスクには、キーストアに応じてキーまたはキー ストアへのアクセスをアプリケーションに許可したり、その他のキー ストア固有の構成手順を行ったりするプロセスが含まれる場合があります。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. たとえば、SQLServerColumnEncryptionJavaKeyStoreProvider を使用する場合は、接続プロパティでキーストアの場所とパスワードを指定する必要があります。For example, for using the SQLServerColumnEncryptionJavaKeyStoreProvider, you need to provide the location and the password of the keystore in the connection properties.

これらのキーストアプロバイダーについては、以降のセクションで詳しく説明します。All of these keystore providers are described in more detail in the sections that follow. Always Encrypted を使用するには、キーストアプロバイダーを1つだけ実装する必要があります。You only need to implement one keystore provider to use Always Encrypted.

Azure Key Vault プロバイダーを使用するUsing Azure Key Vault provider

Azure Key Vault は、特にアプリケーションが Azure でホストされている場合、Always Encrypted の列マスター キーの格納と管理に便利なオプションです。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). Microsoft JDBC Driver for SQL Server には、Azure Key Vault にキーが格納されているアプリケーション用の組み込みプロバイダー SQLServerColumnEncryptionAzureKeyVaultProvider が含まれています。The Microsoft JDBC Driver for SQL Server includes a built-in provider, SQLServerColumnEncryptionAzureKeyVaultProvider, for applications that have keys stored in Azure Key Vault. このプロバイダーの名前は AZURE_KEY_VAULT です。The name of this provider is AZURE_KEY_VAULT. Azure Key Vault ストアプロバイダーを使用するには、アプリケーション開発者が Azure Key Vault でコンテナーとキーを作成し、Azure Active Directory でアプリの登録を作成する必要があります。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. 登録されたアプリケーションには、Always Encrypted で使用するために作成されたキーコンテナーに対して定義されているアクセスポリシーで、Get、Encrypt、Encrypt、Wrap キー、Wrap キー、および Verify アクセス許可が付与されている必要があります。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. キーコンテナーを設定し、列マスターキーを作成する方法の詳細については、「 Azure Key Vault-ステップバイステップ」と「 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.

このページの例では、SQL Server Management Studio を使用して Azure Key Vault ベースの列マスターキーと列暗号化キーを作成した場合、それらを再作成するための T-sql スクリプトは、次の例のように、独自のKEY_PATHを指定することで、この例のようになります。ENCRYPTED_VALUE: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...
)

Azure Key Vault を使用するには、クライアントアプリケーションで SQLServerColumnEncryptionAzureKeyVaultProvider をインスタンス化し、ドライバーに登録する必要があります。To use the Azure Key Vault, client applications need to instantiate the SQLServerColumnEncryptionAzureKeyVaultProvider and register it with the driver.

SQLServerColumnEncryptionAzureKeyVaultProvider を初期化する例を次に示します。Here is an example of initializing SQLServerColumnEncryptionAzureKeyVaultProvider:

SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);

clientIDは、Azure Active Directory インスタンスのアプリ登録のアプリケーション ID です。clientID is the Application ID of an App registration in an Azure Active Directory instance. clientkeyは、そのアプリケーションに登録されているキーパスワードであり、Azure Key Vault への API アクセスを提供します。clientKey is a Key Password registered under that Application, which provides API access to the Azure Key Vault.

アプリケーションで SQLServerColumnEncryptionAzureKeyVaultProvider のインスタンスを作成した後、アプリケーションは SQLServerConnection () メソッドを使用して、インスタンスをドライバーに登録する必要があります。After the application creates an instance of SQLServerColumnEncryptionAzureKeyVaultProvider, the application must register the instance with the driver using the SQLServerConnection.registerColumnEncryptionKeyStoreProviders() method. インスタンスは、既定の参照名 AZURE_KEY_VAULT を使用して登録することを強くお勧めします。この名前は、SQLServerColumnEncryptionAzureKeyVaultProvider () API を呼び出すことによって取得できます。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. 既定の名前を使用すると、SQL Server Management Studio や PowerShell などのツールを使用して Always Encrypted キーをプロビジョニングして管理することができます (ツールでは、既定の名前を使用してメタデータオブジェクトを列マスターキーに生成します)。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). 次の例は、Azure Key Vault プロバイダーの登録を示しています。The following example shows registering the Azure Key Vault provider. SQLServerConnection () メソッドの詳細については、「 JDBC Driver の ALWAYS ENCRYPTED API リファレンス」を参照してください。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);

重要

Azure Key Vault キーストアプロバイダーを使用する場合、JDBC ドライバーの Azure Key Vault 実装には、アプリケーションに含める必要があるこれらのライブラリ (GitHub から) に依存しています。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-ライブラリ-java ライブラリazure-activedirectory-library-for-java libraries

これらの依存関係を Maven プロジェクトに含める方法の例については、「 Apache Maven を使用した ADAL4J と AKV の依存関係のダウンロード」を参照してください。For an example of how to include these dependencies in a Maven project, see Download ADAL4J And AKV Dependencies with Apache Maven

Windows 証明書ストア プロバイダーの使用Using Windows Certificate Store provider

SQLServerColumnEncryptionCertificateStoreProvider は、列マスター キーを Windows 証明書ストアに格納するために使用できます。The SQLServerColumnEncryptionCertificateStoreProvider can be used to store column master keys in the Windows Certificate Store. データベースに列マスターキーと列暗号化キーの定義を作成するには、SQL Server Management Studio (SSMS) Always Encrypted ウィザードまたはその他のサポートされているツールを使用します。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. 同じウィザードを使用して、Windows 証明書ストアに自己署名証明書を生成し、Always Encrypted データの列マスターキーとして使用することができます。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. 列マスターキーと列暗号化キーの T-sql 構文の詳細については、「列マスターキーの作成」および「列暗号化キーの作成」を参照してください。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.

SQLServerColumnEncryptionCertificateStoreProvider の名前は MSSQL_CERTIFICATE_STORE であり、プロバイダーオブジェクトの getName () API によってクエリを実行できます。The name of the SQLServerColumnEncryptionCertificateStoreProvider is MSSQL_CERTIFICATE_STORE and can be queried by the getName() API of the provider object. これはドライバーによって自動的に登録され、アプリケーションを変更することなくシームレスに使用できます。It's automatically registered by the driver and can be used seamlessly without any application change.

このページの例では、SQL Server Management Studio を使用して Windows 証明書ストアベースの列マスターキーと列暗号化キーを作成した場合、T-sql スクリプトを再作成するには、次の例のように、独自の KEY_ を使用します。 パスENCRYPTED_VALUE: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...
)

重要

この記事の他のキーストアプロバイダーは、ドライバーでサポートされているすべてのプラットフォームで利用できますが、JDBC ドライバーの SQLServerColumnEncryptionCertificateStoreProvider 実装は、Windows オペレーティングシステムでのみ使用できます。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. このファイルは、ドライバーパッケージで使用できる sqljdbc_auth に依存しています。It has a dependency on the sqljdbc_auth.dll that is available in the driver package. このプロバイダーを使用するには、JDBC ドライバーがインストールされているコンピューターの Windows システム パス上のディレクトリに sqljdbc_auth.dll ファイルをコピーします。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. または、java.library.path システム プロパティを設定して sqljdbc_auth.dll のディレクトリを指定することもできます。Alternatively you can set the java.library.path system property to specify the directory of the sqljdbc_auth.dll. 32 ビットの Java 仮想マシン (JVM) を実行している場合は、オペレーティング システムのバージョンが x64 であっても、x86 フォルダーの sqljdbc_auth.dll ファイルを使用してください。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. 64 ビットの JVM を x64 プロセッサ上で実行している場合は、x64 フォルダーの sqljdbc_auth.dll ファイルを使用してください。If you are running a 64-bit JVM on a x64 processor, use the sqljdbc_auth.dll file in the x64 folder. たとえば、32 ビットの JVM を使用していて、JDBC ドライバーが既定のディレクトリにインストールされている場合、Java アプリケーションの起動時に次の仮想マシン (VM) 引数を使用することで、DLL の場所を指定できます。-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

Java キーストアプロバイダーの使用Using Java Key Store provider

JDBC ドライバーには、Java キー ストアの組み込みキー ストア プロバイダー実装が含まれています。The JDBC driver comes with a built-in keystore provider implementation for the Java Key Store. 接続文字列にkeyStoreAuthentication接続文字列プロパティが存在し、それが "JavaKeyStorePassword" に設定されている場合、ドライバーは自動的に Java キーストアのプロバイダーをインスタンス化して登録します。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. Java キーストアプロバイダーの名前は MSSQL_JAVA_KEYSTORE です。The name of the Java Key Store provider is MSSQL_JAVA_KEYSTORE. この名前は、SQLServerColumnEncryptionJavaKeyStoreProvider () API を使用して照会することもできます。This name can also be queried by using the SQLServerColumnEncryptionJavaKeyStoreProvider.getName() API.

クライアントアプリケーションが Java キーストアに対する認証に必要な資格情報を指定できる接続文字列プロパティは3つあります。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. ドライバーは、接続文字列のこれら3つのプロパティの値に基づいて、プロバイダーを初期化します。The driver initializes the provider based on the values of these three properties in the connection string.

keyStoreAuthentication: 使用する Java キーストアを識別します。keyStoreAuthentication: Identifies the Java Key Store to use. SQL Server 用に Microsoft JDBC Driver 6.0 以降を使用している場合は、このプロパティを介してのみ Java キーストアに対して認証を行うことができます。With Microsoft JDBC Driver 6.0 and higher for SQL Server, you can authenticate to the Java Key Store only through this property. Java キーストアの場合、このプロパティの値はでJavaKeyStorePasswordある必要があります。For the Java Key Store, the value for this property must be JavaKeyStorePassword.

keyStoreLocation: 列マスターキーを格納する Java キーストアファイルへのパス。keyStoreLocation: The path to the Java Key Store file that stores the column master key. パスには、キーストアファイル名が含まれます。The path includes the keystore filename.

keyStoreSecret: キーストアとキーの両方に使用するシークレット/パスワード。keyStoreSecret: The secret/password to use for the keystore as well as for the key. Java キーストアを使用する場合、キーストアとキーパスワードは同じである必要があります。For using the Java Key Store, the keystore and the key password must be the same.

これらの資格情報を接続文字列に指定する例を次に示します。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>";

これらの設定は、SQLServerDataSource オブジェクトを使用して取得または設定することもできます。You can also get or set these settings using the SQLServerDataSource object. 詳細については、「 JDBC Driver の ALWAYS ENCRYPTED API リファレンス」を参照してください。For more information, see Always Encrypted API Reference for the JDBC Driver.

これらの資格情報が接続プロパティに存在する場合、JDBC ドライバーは自動的に SQLServerColumnEncryptionJavaKeyStoreProvider をインスタンス化します。The JDBC driver automatically instantiates the SQLServerColumnEncryptionJavaKeyStoreProvider when these credentials are present in connection properties.

Java キーストアの列マスターキーを作成するCreating a column master key for the Java Key Store

SQLServerColumnEncryptionJavaKeyStoreProvider は、JKS または PKCS12 キーストアの種類で使用できます。The SQLServerColumnEncryptionJavaKeyStoreProvider can be used with JKS or PKCS12 keystore types. このプロバイダーで使用するキーを作成またはインポートするには、Java keytoolユーティリティを使用します。To create or import a key to use with this provider use the Java keytool utility. キーは、キーストア自体と同じパスワードを持っている必要があります。The key must have the same password as the keystore itself. 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

このコマンドは、公開キーを作成し、x.509 自己署名証明書にラップします。これは、キーストア ' キーストア ' に格納され、関連付けられている秘密キーと共に格納されます。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. キーストア内のこのエントリは、エイリアス ' AlwaysEncryptedKey ' によって識別されます。This entry in the keystore is identified by the alias 'AlwaysEncryptedKey'.

次に、PKCS12 ストア型を使用した場合の例を示します。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

キーストアの種類が PKCS12 の場合、keytool ユーティリティはキーのパスワードの入力を要求しません。キーのパスワードは-キーパスワードを指定する必要があります。 SQLServerColumnEncryptionJavaKeyStoreProvider ではキーストアとキーが同じである必要があるためです。入力.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.

また、.pfx 形式で Windows 証明書ストアから証明書をエクスポートし、それを SQLServerColumnEncryptionJavaKeyStoreProvider と共に使用することもできます。You can also export a certificate from the Windows Certificate store in .pfx format and use that with the SQLServerColumnEncryptionJavaKeyStoreProvider. エクスポートされた証明書は、JKS キーストア型として Java キーストアにインポートすることもできます。The exported certificate can also be imported to the Java Key Store as a JKS keystore type.

Keytool エントリを作成した後、データベースに列マスターキーのメタデータを作成します。これには、キーストアプロバイダー名とキーパスが必要です。After creating the keytool entry, create the column master key metadata in the database, which needs the keystore provider name and the key path. 列マスターキーのメタデータを作成する方法の詳細については、「 CREATE COLUMN MASTER key」を参照してください。For more information on how to create column master key meta data, see CREATE COLUMN MASTER KEY. SQLServerColumnEncryptionJavaKeyStoreProvider の場合、キーのパスはキーのエイリアスにすぎず、SQLServerColumnEncryptionJavaKeyStoreProvider の名前は ' 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'. また、SQLServerColumnEncryptionJavaKeyStoreProvider クラスの getName () パブリック API を使用して、この名前を照会することもできます。You can also query this name using the getName() public API of the SQLServerColumnEncryptionJavaKeyStoreProvider class.

列マスターキーを作成するための T-sql 構文は次のとおりです。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>'
)

上記で作成した ' AlwaysEncryptedKey ' では、列マスターキーの定義は次のようになります。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'
)

注意

組み込みの SQL Server management Studio 機能では、Java キーストアの列マスターキー定義を作成することはできません。The built-in SQL Server management Studio functionality cannot create column master key definitions for the Java Key Store. T-sql コマンドはプログラムで使用する必要があります。T-SQL commands must be used programmatically.

Java キーストアの列暗号化キーの作成Creating a column encryption key for the Java Key Store

SQL Server Management Studio またはその他のツールを使用して、Java キーストアの列マスターキーを使用して列暗号化キーを作成することはできません。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. クライアントアプリケーションは、SQLServerColumnEncryptionJavaKeyStoreProvider クラスを使用して、プログラムで列暗号化キーを作成する必要があります。The client application must create the column encryption key programmatically using the SQLServerColumnEncryptionJavaKeyStoreProvider class. 詳細については、「プログラムによるキーのプロビジョニングに列マスターキーストアプロバイダーを使用する」を参照してください。For more information, see Using column master key store providers for programmatic key provisioning.

カスタム列マスター キー ストア プロバイダーを実装するImplementing a custom column master key store provider

既存のプロバイダーでサポートされていないキー ストアに列マスター キーを格納する場合は、SQLServerColumnEncryptionKeyStoreProvider クラスを拡張し、SQLServerConnection.registerColumnEncryptionKeyStoreProviders() メソッドを使用してプロバイダーを登録して、カスタム プロバイダーを実装できます。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
    }
}

プロバイダーを登録します。Register the provider:

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

プログラムによるキーのプロビジョニングに列マスター キー ストア プロバイダーを使用するUsing column master key store providers for programmatic key provisioning

Microsoft JDBC Driver for SQL Server は、暗号化された列にアクセスする際に、列暗号化キーを暗号化解除するための適切な列マスター キー ストア プロバイダーを透過的に検索して呼び出します。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. 一般的に、通常のアプリケーション コードは列マスター キー ストア プロバイダーを直接呼び出しません。Typically, your normal application code doesn't directly call column master key store providers. ただし、Always Encrypted キーをプロビジョニングして管理するために、プログラムによってプロバイダーをインスタンス化して呼び出すことができます。You may, however, instantiate and call a provider programmatically to provision and manage Always Encrypted keys. この手順は、暗号化された列暗号化キーを生成し、列のマスターキーのローテーションとして列暗号化キーを復号化するために実行できます。たとえば、のようになります。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. 詳細については、「 Overview of Key Management for Always Encrypted(Always Encrypted のキー管理の概要)」を参照してください。For more information, see Overview of Key Management for Always Encrypted.

カスタム キー ストア プロバイダーを使用する場合、独自のキー管理ツールの実装が必要になることがあります。If you use a custom keystore provider, implementing your own key management tools may be required. Windows 証明書ストアまたは Azure Key Vault に格納されているキーを使用する場合は、SQL Server Management Studio や PowerShell などの既存のツールを使用して、キーの管理とプロビジョニングを行うことができます。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. Java キーストアに格納されているキーを使用する場合は、プログラムによってキーをプロビジョニングする必要があります。When using keys stored in the Java Key Store, you need to provision keys programmatically. 次の例は、SQLServerColumnEncryptionJavaKeyStoreProvider クラスを使用して、Java キーストアに格納されているキーを使用してキーを暗号化する方法を示しています。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();
    }
}

アプリケーション クエリで Always Encrypted を有効にするEnabling Always Encrypted for application queries

パラメーターの暗号化と、暗号化された列をターゲットとするクエリ結果の暗号化解除を有効にする最も簡単な方法としては、columnEncryptionSetting 接続文字列キーワードの値を 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.

次の接続文字列は、JDBC ドライバーで Always Encrypted を有効にする例です。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);

次のコードは、SQLServerDataSource オブジェクトを使用した場合と同等の例です。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 は、個々のクエリに対しても有効にすることができます。Always Encrypted can also be enabled for individual queries. 詳細については、「Always Encrypted のパフォーマンスの影響を制御する」をご覧ください。For more information, see Controlling the performance impact of Always Encrypted. 暗号化または暗号化解除を正常に行うには、Always Encrypted を有効にするだけでは不十分です。Enabling Always Encrypted isn't sufficient for encryption or decryption to succeed. 次のことを確認する必要もあります。You also need to make sure:

  • アプリケーションが、データベース内の Always Encrypted キーに関するメタデータへのアクセスに必要な VIEW ANY COLUMN MASTER KEY DEFINITION および VIEW ANY COLUMN ENCRYPTION KEY DEFINITION データベース権限を持っている。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. 詳細については、「Always Encrypted (データベース エンジン)」のページで権限に関するセクションを参照してください。For details, see Permissions in Always Encrypted (Database Engine).
  • アプリケーションが、列暗号化キーを保護する列マスター キーにアクセスでき、クエリされたデータベース列を暗号化する。The application can access the column master key that protects the column encryption keys, which encrypt the queried database columns. Java キーストアプロバイダーを使用するには、接続文字列に追加の資格情報を提供する必要があります。To use the Java Key Store provider, you need to provide additional credentials in the connection string. 詳細については、「 Java キーストアプロバイダーの使用」を参照してください。For more information, see Using Java Key Store provider.

java.sql.Time の値をサーバーに送信する方法の構成Configuring how java.sql.Time values are sent to the server

java.sql.Time 値のサーバーへの送信方法を構成するために、sendTimeAsDatetime 接続プロパティを使用します。The sendTimeAsDatetime connection property is used to configure how the java.sql.Time value is sent to the server. False に設定すると、時刻値は SQL Server の時刻型として送信されます。When set to false, the time value is sent as a SQL Server time type. True に設定すると、時刻値は datetime 型として送信されます。When set to true, the time value is sent as a datetime type. Time 列が暗号化されている場合、暗号化された列では time から datetime への変換がサポートされていないため、 sendTimeAsDatetimeプロパティは false に設定する必要があります。If a time column is encrypted, the sendTimeAsDatetime property must be false, as encrypted columns don't support the conversion from time to datetime. また、このプロパティは既定で true になっているため、暗号化された時刻列を使用する場合は false に設定する必要があります。Also note that this property is by default true, so when using encrypted time columns you'll have to set it to false. それ以外の場合、ドライバーは例外をスローします。Otherwise, the driver will throw an exception. ドライバーのバージョン6.0 以降では、SQLServerConnection クラスには、このプロパティの値をプログラムで構成する2つのメソッドがあります。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)
  • public boolean getSendTimeAsDatetime()public boolean getSendTimeAsDatetime()

このプロパティの詳細については、「 java の時刻値をサーバーに送信する方法の構成」を参照してください。For more information on this property, see Configuring How java.sql.Time Values are Sent to the Server.

文字列値をサーバーに送信する方法の構成Configuring how String values are sent to the server

SendStringParametersAsUnicode接続プロパティは、文字列値を SQL Server に送信する方法を構成するために使用されます。The sendStringParametersAsUnicode connection property is used to configure how String values are sent to SQL Server. true に設定されている場合、サーバーには Unicode 形式で文字列パラメーターが送信されます。If set to true, String parameters are sent to the server in Unicode format. False に設定されている場合、文字列パラメーターは Unicode ではなく、ASCII や MBCS などの非 Unicode 形式で送信されます。If set to false, String parameters are sent in non-Unicode format, such as ASCII or MBCS, instead of Unicode. このプロパティの既定値は、true です。The default value for this property is true. Always Encrypted が有効になっていて、char/varchar/varchar (max) 列が暗号化されている場合、 sendStringParametersAsUnicodeの値を false に設定する必要があります。When Always Encrypted is enabled and a char/varchar/varchar(max) column is encrypted, the value of sendStringParametersAsUnicode must be set to false. このプロパティが true に設定されている場合、Unicode 文字を含む暗号化された char/varchar/varchar (max) 列からデータを復号化するときに、ドライバーは例外をスローします。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. このプロパティの詳細については、「接続プロパティの設定」を参照してください。For more information on this property, see Setting the Connection Properties.

暗号化された列のデータを取得および変更するRetrieving and modifying data in encrypted columns

アプリケーションクエリの Always Encrypted を有効にすると、標準の JDBC Api を使用して、暗号化されたデータベース列のデータを取得または変更できます。Once you enable Always Encrypted for application queries, you can use standard JDBC APIs to retrieve or modify data in encrypted database columns. アプリケーションが必要なデータベース権限を持っていて、列マスターキーにアクセスできる場合、ドライバーは暗号化された列を対象とするすべてのクエリパラメーターを暗号化し、暗号化された列から取得されるデータを復号化します。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.

Always Encrypted が有効でない場合、暗号化された列をターゲットとするパラメーターを含むクエリは失敗します。If Always Encrypted isn't enabled, queries with parameters that target encrypted columns will fail. 暗号化された列をターゲットとするパラメーターがクエリにない場合、クエリでは、暗号化された列からデータを取得できます。Queries can still retrieve data from encrypted columns as long as the query has no parameters targeting encrypted columns. ただし、ドライバーは、暗号化された列から取得された値を暗号化解除しようとせず、アプリケーションは、暗号化されたバイナリ データを (バイト配列として) 受け取ります。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).

次の表は、Always Encrypted が有効かどうかに応じたクエリの動作をまとめたものです。The following table summarizes the behavior of queries depending on whether Always Encrypted is enabled or not:

クエリの特性Query characteristic Always Encrypted が有効になっており、アプリケーションがキーとキー メタデータにアクセスできるAlways Encrypted is enabled and application can access the keys and key metadata Always Encrypted が有効になっており、アプリケーションがキーまたはキー メタデータにアクセスできないAlways Encrypted is enabled and application can't access the keys or key metadata Always Encrypted が無効になっているAlways Encrypted is disabled
暗号化された列をターゲットとするパラメーターを含むクエリ。Queries with parameters targeting encrypted columns. パラメーター値は透過的に暗号化されます。Parameter values are transparently encrypted. ErrorError ErrorError
暗号化された列をターゲットとするパラメーターを含まず、暗号化された列からデータを取得するクエリ。Queries retrieving data from encrypted columns without parameters targeting encrypted columns. 暗号化された列の結果は透過的に暗号化解除されます。Results from encrypted columns are transparently decrypted. アプリケーションは、暗号化された列用に構成された SQL Server 型に対応する、JDBC データ型のプレーンテキスト値を受け取ります。The application receives plaintext values of the JDBC datatypes corresponding to the SQL Server types configured for the encrypted columns. ErrorError 暗号化された列の結果は暗号化解除されません。Results from encrypted columns aren't decrypted. アプリケーションは、暗号化された値をバイト配列 (byte[]) として受け取ります。The application receives encrypted values as byte arrays (byte[]).

暗号化されたデータの例の挿入と取得Inserting and retrieving encrypted data examples

次の例は、暗号化された列のデータを取得および変更する方法を示しています。The following examples illustrate retrieving and modifying data in encrypted columns. この例では、次のスキーマおよび暗号化された SSN 列と誕生日列を含むターゲットテーブルを想定しています。The examples assume the target table with the following schema and encrypted SSN and BirthDate columns. "MyCMK" という名前の列マスターキーと "Mycmk" という名前の列暗号化キー (前述の「キーストアプロバイダー」セクションで説明) を構成した場合は、次のスクリプトを使用してテーブルを作成できます。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

各 Java コード例では、メモした場所にキーストア固有のコードを挿入する必要があります。For each Java code example, you'll need to insert keystore-specific code in the location noted.

Azure Key Vault キーストアプロバイダーを使用している場合: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;";

Windows 証明書ストアのキーストアプロバイダーを使用している場合:If you're using a Windows Certificate Store keystore provider:

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

Java キーストアのキーストアプロバイダーを使用している場合は、次のようにします。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>";

データの挿入の例Inserting data example

この例では、Patients テーブルに列を挿入します。This example inserts a row into the Patients table. 次の項目に注意してください。Note the following items:

  • このサンプル コードの暗号化に固有のものは何もありません。There's nothing specific to encryption in the sample code. Microsoft JDBC Driver for SQL Server は、暗号化された列を対象とするパラメーターを自動的に検出して暗号化します。The Microsoft JDBC Driver for SQL Server automatically detects and encrypts the parameters that target encrypted columns. この動作により、アプリケーションに対して暗号化が透過的に実行されます。This behavior makes encryption transparent to the application.
  • 暗号化された列を含む、データベースの列に挿入された値は、SQLServerPreparedStatement を使用してパラメーターとして渡されます。The values inserted into database columns, including the encrypted columns, are passed as parameters using SQLServerPreparedStatement. 暗号化されていない列に値を送信する場合、パラメーターの使用は省略可能です (ただし、SQL インジェクションを防ぐのに役立つので、強くお勧めします) が、暗号化された列をターゲットとする値に対しては必須です。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. 暗号化された列に挿入された値がクエリステートメントに埋め込まれているリテラルとして渡された場合、ドライバーはターゲットの暗号化された列の値を特定できず、値を暗号化しないため、クエリは失敗します。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. その結果、サーバーはこれらの値を、暗号化された列と互換性がないと見なして拒否します。As a result, the server would reject them as incompatible with the encrypted columns.
  • Microsoft JDBC Driver for SQL Server は、暗号化された列から取得されたデータを透過的に暗号化解除するので、プログラムで印刷される値はすべてプレーンテキストになります。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.
  • WHERE 句を使用して検索を実行する場合は、ドライバーがデータベースに送信する前にその値を透過的に暗号化できるように、WHERE 句で使用される値をパラメーターとして渡す必要があります。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. 次の例では、SSN はパラメーターとして渡されますが、lastname は暗号化されていないので、LastName はリテラルとして渡されます。In the following example, the SSN is passed as a parameter but the LastName is passed as a literal as LastName isn't encrypted.
  • SSN 列をターゲットとするパラメーターに使用される setter メソッドは setString () であり、char/varchar SQL Server データ型にマップされます。The setter method used for the parameter targeting the SSN column is setString(), which maps to the char/varchar SQL Server data type. このパラメーターに対して使用されている setter メソッドが setNString () だった場合、nchar/nvarchar にマップされ、クエリは失敗します。これは、暗号化された nchar/nvarchar 値から暗号化された char/varchar 値への変換が Always Encrypted でサポートされていないためです。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();
}

プレーンテキスト データの取得の例Retrieving plaintext data example

次の例は、暗号化された値に基づいてデータをフィルター処理し、暗号化された列からプレーンテキスト データを取得する方法を示しています。The following example demonstrates filtering data based on encrypted values and retrieving plaintext data from encrypted columns. 次の項目に注意してください。Note the following items:

  • SSN 列に対してフィルター処理するために WHERE 句で使用される値は、Microsoft JDBC Driver for SQL Server がデータベースに送信する前に透過的に暗号化できるように、パラメーターとして渡す必要があります。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.
  • Microsoft JDBC Driver for SQL Server は、SSN 列と BirthDate 列から取得されたデータを透過的に暗号化解除するので、プログラムで印刷される値はすべてプレーンテキストになります。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.

注意

決定論的暗号化を使用して列が暗号化される場合、クエリは列に対して等価比較を実行できます。if columns are encrypted using deterministic encryption, queries can perform equality comparisons on them. 詳細については、「Always Encrypted (データベース エンジン)」の「明確な暗号化またはランダム化された暗号化の選択」を参照してください。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();
}

暗号化されたデータの取得の例Retrieving encrypted data example

Always Encrypted が有効になっていない場合でも、暗号化された列をターゲットとするパラメーターをクエリが含んでいなければ、クエリでは、暗号化された列からデータを取得できます。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.

次の例は、暗号化された列から暗号化されたバイナリ データを取得する方法を示しています。The following example illustrates retrieving binary encrypted data from encrypted columns. 次の項目に注意してください。Note the following items:

  • 接続文字列で Always Encrypted が有効になっていないので、クエリは、SSN と BirthDate の暗号化された値をバイト配列として返します (プログラムによって値が文字列に変換されます)。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).
  • Always Encrypted が無効の状態で、暗号化された列からデータを取得するクエリは、暗号化された列をターゲットとするパラメーターがない場合に限り、パラメーターを含むことができます。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. 次のクエリは、データベースで暗号化されない LastName によってフィルター処理を行います。The following query filters by LastName, which isn't encrypted in the database. クエリが SSN または BirthDate によってフィルター処理を行った場合、クエリは失敗します。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();
}

暗号化された列をクエリする際の一般的な問題を回避するAvoiding common problems when querying encrypted columns

ここでは、暗号化された列を Java アプリケーションからクエリする際のエラーの一般的なカテゴリと、その対処方法に関するいくつかのガイドラインを示します。This section describes common categories of errors when querying encrypted columns from Java applications and a few guidelines on how to avoid them.

サポートされていないデータ型の変換エラーUnsupported data type conversion errors

Always Encrypted では、暗号化されたデータ型に対するいくつかの変換がサポートされています。Always Encrypted supports few conversions for encrypted data types. サポートされている型の変換の詳細な一覧については、「Always Encrypted (データベース エンジン)」を参照してください。See Always Encrypted (Database Engine) for the detailed list of supported type conversions. データ型の変換エラーを回避するには、Here is what you can do to avoid data type conversion errors. 次のことを確認してください。Make sure that:

  • 暗号化された列をターゲットとするパラメーターの値を渡すときは、適切な setter メソッドを使用します。you use the proper setter methods when passing values for parameters that target encrypted columns. パラメーターの SQL Server データ型が、ターゲット列の型とまったく同じであること、またはパラメーターの SQL Server データ型を列の対象の型に変換することがサポートされていることを確認してください。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. 特定の SQL Server データ型に対応するパラメーターを渡すために、API メソッドが SQLServerPreparedStatement、SQLServerCallableStatement、および SQLServerResultSet クラスに追加されました。API methods have been added to the SQLServerPreparedStatement, SQLServerCallableStatement, and SQLServerResultSet classes to pass parameters corresponding to specific SQL Server data types. たとえば、列が暗号化されていない場合は、setTimestamp () メソッドを使用して、パラメーターを datetime2 または datetime 列に渡すことができます。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. ただし、列が暗号化されている場合は、データベース内の列の型を表す正確なメソッドを使用する必要があります。But when a column is encrypted you'll have to use the exact method representing the type of the column in the database. たとえば、setTimestamp () を使用して、暗号化された datetime2 列に値を渡し、Settimestamp () を使用して、暗号化された datetime 列に値を渡すことができます。For example, use setTimestamp() to pass values to an encrypted datetime2 column and use setDateTime() to pass values to an encrypted datetime column. 新しい Api の完全な一覧については、JDBC Driver の ALWAYS ENCRYPTED API リファレンスを参照してください。See Always Encrypted API Reference for the JDBC Driver for a complete list of new APIs.
  • 10 進数と数値の SQL Server データ型の列をターゲットとするパラメーターの有効桁数と小数点以下桁数が、ターゲット列に対して構成された有効桁数と小数点と同じである。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 メソッドが SQLServerPreparedStatement、SQLServerCallableStatement、および SQLServerResultSet クラスに追加され、decimal および numeric データ型を表すパラメーターまたは列のデータ値と共に、有効桁数と小数点以下桁数を受け入れるようになりました。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. 新しい Api とオーバーロードされた Api の完全な一覧については、「JDBC Driver の ALWAYS ENCRYPTED API リファレンス」を参照してください。See Always Encrypted API Reference for the JDBC Driver for a complete list of new/overloaded APIs.
  • datetime2、datetimeoffset、または time SQL Server の列をターゲットとするパラメーターの秒の小数部の有効桁数/小数点以下桁数が、ターゲット列の値を変更するクエリの対象列の秒の小数部の有効桁数/小数点以下桁数よりも大きくありません。.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 メソッドは、SQLServerPreparedStatement、SQLServerCallableStatement、および SQLServerResultSet クラスに追加され、秒の小数部の有効桁数/小数点以下桁数と、これらのデータ型を表すパラメーターのデータ値を受け入れるようになりました。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. 新しい/オーバーロードされた Api の完全な一覧については、 JDBC Driver の ALWAYS ENCRYPTED API リファレンスを参照してください。For a complete list of new/overloaded APIs, see Always Encrypted API Reference for the JDBC Driver.

接続プロパティが正しくないために発生するエラーErrors due to incorrect connection properties

このセクションでは、Always Encrypted データを使用するように接続設定を適切に構成する方法について説明します。This section describes how to configure connection settings properly to use Always Encrypted data. 暗号化されたデータ型は限定的な変換をサポートしているため、暗号化された列を使用する場合、 sendTimeAsDatetimesendStringParametersAsUnicodeの接続設定で適切な構成が必要になります。Since encrypted data types support limited conversions, the sendTimeAsDatetime and sendStringParametersAsUnicode connection settings need proper configuration when using encrypted columns. 次のことを確認してください。Make sure that:

暗号化された値の代わりにプレーンテキストを渡すことによるエラーErrors due to passing plaintext instead of encrypted values

暗号化された列をターゲットとするすべての値は、アプリケーションの内部で暗号化される必要があります。Any value that targets an encrypted column needs to be encrypted inside the application. 暗号化された列でプレーンテキスト値を挿入/変更したり、この値によってフィルター処理を行おうとしたりすると、次のようなエラーになります。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'

このようなエラーを防ぐには、次のことを確認してください。To prevent such errors, make sure:

  • Always Encrypted が、暗号化された列をターゲットとするアプリケーション クエリに対して有効になっている (接続文字列または特定のクエリで)。Always Encrypted is enabled for application queries targeting encrypted columns (for the connection string or for a specific query).
  • 準備されたステートメントとパラメーターを使用して、暗号化された列をターゲットとするデータを送信します。you use prepared statements and parameters to send data targeting encrypted columns. 次の例は、パラメーターとしてリテラルを渡す代わりに、暗号化された列 (SSN) でリテラル/定数によって不正なフィルター処理を行うクエリを示しています。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. このクエリは失敗します。This query will fail:
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM Customers WHERE SSN='795-73-9838'");

入力パラメーターの暗号化を強制するForce encryption on input parameters

強制暗号化機能では、Always Encrypted を使用する場合に、パラメーターの暗号化が適用されます。The Force Encryption feature enforces encryption of a parameter when using Always Encrypted. 強制的な暗号化が使用され、パラメーターの暗号化が不要であることが SQL Server からドライバーに通知された場合、このパラメーターを使用するクエリは失敗します。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. 攻撃を受けた SQL Server がクライアントに不正な暗号化メタデータを提供すると、データ漏えいが引き起こされる可能性がありますが、このプロパティは、そのようなセキュリティ攻撃に対する保護を強化します。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. SQLServerPreparedStatement クラスと SQLServerCallableStatement クラスの set * メソッドと SQLServerResultSet クラスの* update メソッドは、ブール型の引数を受け取り、force encryption 設定を指定するようにオーバーロードされています。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. この引数の値が false の場合、ドライバーはパラメーターの暗号化を強制しません。If the value of this argument is false, the driver won't force encryption on parameters. Force encryption が true に設定されている場合、クエリパラメーターは、送信先列が暗号化され、接続またはステートメントで Always Encrypted が有効になっている場合にのみ送信されます。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. このプロパティを使用すると、セキュリティがさらに強化され、暗号化されることが予想される場合に、ドライバーがプレーンテキストとして SQL Server に誤ってデータを送信することがなくなります。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.

強制暗号化設定でオーバーロードされる SQLServerPreparedStatement メソッドと SQLServerCallableStatement メソッドの詳細については、「 JDBC Driver の ALWAYS ENCRYPTED API リファレンス」を参照してください。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

Always Encrypted のパフォーマンスの影響を制御するControlling the performance impact of Always Encrypted

Always Encrypted はクライアント側暗号化テクノロジであるため、ほとんどのパフォーマンス オーバーヘッドは、データベースではなくクライアント側で発生します。Because Always Encrypted is a client-side encryption technology, most of the performance overhead is observed on the client side, not in the database. 暗号化および暗号化解除の操作のコストとは別に、クライアント側のパフォーマンス オーバーヘッドのその他の原因を次に示します。Apart from the cost of encryption and decryption operations, other sources of performance overheads on the client side are:

  • クエリ パラメーターのメタデータを取得するためのデータベースへの追加のラウンド トリップ。Additional round trips to the database to retrieve metadata for query parameters.
  • 列マスター キーにアクセスするための列マスター キー ストアの呼び出し。Calls to a column master key store to access a column master key.

このセクションでは、Microsoft JDBC Driver for SQL Server の組み込みのパフォーマンス最適化、および上記の 2 つの要因によるパフォーマンスへの影響を制御する方法について説明します。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.

クエリ パラメーターのメタデータを取得するためのラウンド トリップを制御するControlling round trips to retrieve metadata for query parameters

既定では、接続に対して Always Encrypted が有効になっている場合、ドライバーは、各パラメーター化クエリに対して sys.sp_describe_parameter_encryption を呼び出し、クエリ ステートメント (パラメーター値を除く) を SQL Server に渡します。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. sys.sp_describe_parameter_encryption はクエリ ステートメントを分析して、パラメーターを暗号化する必要があるかどうかを判断し、必要がある場合は、これらの各パラメーターに対して暗号化関連の情報を返します。この情報により、ドライバーはパラメーター値を暗号化できます。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. この動作により、クライアント アプリケーションに対する高度な透明性が確保されます。This behavior ensures a high level of transparency to the client application. アプリケーションでパラメーターを使用して、暗号化された列を対象とする値をドライバーに渡す限り、アプリケーション (およびアプリケーション開発者) は、暗号化された列にアクセスするクエリを認識する必要はありません。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.

クエリ レベルで Always Encrypted を設定するSetting Always Encrypted at the query level

パラメーター化クエリに対して暗号化メタデータを取得することによるパフォーマンスへの影響を制御するには、Always Encrypted を接続に対して設定する代わりに、個々のクエリに対して有効にします。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. これにより、暗号化された列をターゲットとするパラメーターを含むことがわかっているクエリに対してのみ、sys.sp_describe_parameter_encryption が呼び出されるように設定できます。This way you can ensure that sys.sp_describe_parameter_encryption is invoked only for queries that you know have parameters targeting encrypted columns. ただし、これにより、暗号化の透明度が損なわれることに注意してください。データベース列の暗号化プロパティを変更する場合は、スキーマの変更に合わせてアプリケーション コードの変更が必要になる可能性があります。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.

個々のクエリの Always Encrypted 動作を制御するには、列挙型 SQLServerStatementColumnEncryptionSetting を渡すことによって個々のステートメントオブジェクトを構成する必要があります。これは、読み取りと書き込み時のデータの送受信方法を指定します。その特定のステートメントの暗号化された列。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. 有用なガイドラインを次に示します。Here are some useful guidelines:

  • クライアント アプリケーションがデータベース接続を介して送信するほとんどのクエリが、暗号化された列にアクセスする場合は、次のガイドラインを使用してください。If most queries a client application sends over a database connection access encrypted columns, use these guidelines:

    • columnEncryptionSetting 接続文字列キーワードを Enabled に設定します。Set the columnEncryptionSetting connection string keyword to Enabled.
    • 暗号化された列にアクセスしない個々のクエリに対して、SQLServerStatementColumnEncryptionSetting.Disabled を設定します。Set SQLServerStatementColumnEncryptionSetting.Disabled for individual queries that don't access any encrypted columns. この設定により、sys.sp_describe_parameter_encryption の呼び出しと、結果セット内の値を暗号化解除しようとする試みの両方が無効になります。This setting will disable both calling sys.sp_describe_parameter_encryption as well as an attempt to decrypt any values in the result set.
    • 暗号化を必要とするパラメーターを含まないが、暗号化された列からデータを取得する個々のクエリに対して、SQLServerStatementColumnEncryptionSetting.ResultSet を設定します。Set SQLServerStatementColumnEncryptionSetting.ResultSet for individual queries that don't have any parameters requiring encryption but retrieve data from encrypted columns. この設定により、sys.sp_describe_parameter_encryption の呼び出しと、パラメーター暗号化が無効になります。This setting will disable calling sys.sp_describe_parameter_encryption and parameter encryption. クエリは、暗号化列の結果を暗号化解除できます。The query will be able to decrypt the results from encryption columns.
  • クライアント アプリケーションがデータベース接続を介して送信するほとんどのクエリが、暗号化された列にアクセスしない場合は、次のガイドラインを使用してください。If most queries a client application sends over a database connection don't access encrypted columns, use these guidelines:

    • columnEncryptionSetting 接続文字列キーワードを Disabled に設定します。Set the columnEncryptionSetting connection string keyword to Disabled.
    • 暗号化を必要とするパラメーターを含む個々のクエリに対して、SQLServerStatementColumnEncryptionSetting.Enabled を設定します。Set SQLServerStatementColumnEncryptionSetting.Enabled for individual queries that have any parameters that need to be encrypted. この設定により、sys.sp_describe_parameter_encryption の呼び出しと、暗号化された列から取得されたクエリ結果の暗号化解除の両方が有効になります。This setting will enable both calling sys.sp_describe_parameter_encryption as well as the decryption of any query results retrieved from encrypted columns.
    • 暗号化を必要とするパラメーターを含まないが、暗号化された列からデータを取得するクエリに対して、SQLServerStatementColumnEncryptionSetting.ResultSet を設定します。Set SQLServerStatementColumnEncryptionSetting.ResultSet for queries that don't have any parameters requiring encryption but retrieve data from encrypted columns. この設定により、sys.sp_describe_parameter_encryption の呼び出しと、パラメーター暗号化が無効になります。This setting will disable calling sys.sp_describe_parameter_encryption and parameter encryption. クエリは、暗号化列の結果を暗号化解除できます。The query will be able to decrypt the results from encryption columns.

SQLServerStatementColumnEncryptionSetting 設定を使用して暗号化を回避し、プレーンテキストデータにアクセスすることはできません。The SQLServerStatementColumnEncryptionSetting settings can't be used to bypass encryption and gain access to plaintext data. ステートメントで列の暗号化を構成する方法の詳細については、 JDBC Driver の ALWAYS ENCRYPTED API リファレンスを参照してください。For more information on how to configure column encryption on a statement, see Always Encrypted API Reference for the JDBC Driver.

次の例では、データベース接続に対して Always Encrypted が無効になっています。In the following example, Always Encrypted is disabled for the database connection. アプリケーションが発行するクエリに、暗号化されていない LastName 列をターゲットとするパラメーターが含まれています。The query the application issues has a parameter that targets the LastName column that isn't encrypted. このクエリは、どちらも暗号化されている SSN 列と BirthDate 列からデータを取得します。The query retrieves data from the SSN and BirthDate columns that are both encrypted. このような場合、暗号化メタデータを取得するために sys.sp_describe_parameter_encryption を呼び出す必要ありません。In such a case, calling sys.sp_describe_parameter_encryption to retrieve encryption metadata isn't required. ただし、アプリケーションが 2 つの暗号化された列からプレーンテキスト値を受け取ることができるよう、クエリ結果の暗号化解除を有効にする必要があります。However, the decryption of the query results needs to be enabled so that the application can receive plaintext values from the two encrypted columns. SQLServerStatementColumnEncryptionSetting 設定を使用して、を確認します。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();
}

列暗号化キーのキャッシュColumn encryption key caching

列暗号化キーを暗号化解除するための列マスター キー ストアの呼び出し回数を減らすために、Microsoft JDBC Driver for SQL Server は、プレーンテキストの列暗号化キーをメモリにキャッシュします。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. 暗号化された列暗号化キー値をデータベース メタデータから受け取った後、ドライバーは、暗号化されたキー値に対応するプレーンテキストの列暗号化キーをまず見つけようとします。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. ドライバーは、暗号化された列暗号化キー値がキャッシュ内に見つからない場合にのみ、列マスター キーを含むキー ストアを呼び出します。The driver calls the keystore containing the column master key only if it cannot find the encrypted column encryption key value in the cache.

SQLServerConnection クラスの setColumnEncryptionKeyCacheTtl () API を使用して、キャッシュ内の列暗号化キーエントリの有効期間の値を構成できます。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. キャッシュ内の列暗号化キーエントリの既定の有効期限の値は2時間です。The default time-to-live value for the column encryption key entries in the cache is two hours. キャッシュを無効にするには、値0を使用します。To turn off caching, use a value of 0. 有効期限を設定するには、次の API を使用します。To set any time-to-live value, use the following API:

SQLServerConnection.setColumnEncryptionKeyCacheTtl (int columnEncryptionKeyCacheTTL, TimeUnit unit)

たとえば、有効期限を10分に設定するには、次のように指定します。For example, to set a time-to-live value of 10 minutes, use:

SQLServerConnection.setColumnEncryptionKeyCacheTtl (10, TimeUnit.MINUTES)

時間単位としては、日、時、分、または秒のみがサポートされます。Only DAYS, HOURS, MINUTES, or SECONDS are supported as the time unit.

SQLServerBulkCopy を使用した暗号化されたデータのコピーCopying encrypted data using SQLServerBulkCopy

SQLServerBulkCopy を使用して、データの暗号化解除を行うことなく、既に暗号化されて 1 つのテーブルに格納されているデータを別のテーブルにコピーできます。With SQLServerBulkCopy, you can copy data that is already encrypted and stored in one table to another table without decrypting the data. この手順は次のとおりです。To do that:

  • ターゲット テーブルの暗号化構成が、ソース テーブルの構成と同じであることを確認します。Make sure the encryption configuration of the target table is identical to the configuration of the source table. 具体的には、両方のテーブルで同じ列が暗号化されており、同じ暗号化タイプおよび同じ暗号化キーを使用してこれらの列が暗号化されている必要があります。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. いずれかのターゲット列が、対応するソース列と異なる方法で暗号化されている場合、コピー操作の後でターゲット テーブル内のデータを暗号化解除することはできません。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. データは破損します。The data will be corrupted.
  • Always Encrypted を有効にせずに、ソース テーブルとターゲット テーブルへの両方のデータベース接続を構成します。Configure both database connections to the source table and to the target table without Always Encrypted enabled.
  • AllowEncryptedValueModifications オプションを設定します。Set the allowEncryptedValueModifications option. 詳細については、「 JDBC ドライバーでの一括コピーの使用」を参照してください。For more information, see Using bulk copy with the JDBC driver.

注意

データベースが破損する可能性があるので、AllowEncryptedValueModifications を指定する際には注意が必要です。このオプションは、データが実際に暗号化されているかどうか、またはターゲット列と同じ暗号化のタイプ、アルゴリズム、およびキーを使用して正しく暗号化されているかどうかを、Microsoft JDBC Driver for SQL Server がチェックしないためです。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.

参照See also

Always Encrypted (データベース エンジン)Always Encrypted (Database Engine)