Az Always Encrypted használata a JDBC-illesztővel

JDBC-illesztőprogram letöltése

Ez az oldal tájékoztatást nyújt arról, hogyan fejleszthet Java-alkalmazásokat az Always Encrypted használatához a Microsoft JDBC Driver 6.0-s (vagy újabb) verziójával az SQL Serverhez.

Az Always Encrypted lehetővé teszi az ügyfelek számára a bizalmas adatok titkosítását, és soha nem fedik fel az adatokat vagy a titkosítási kulcsokat az SQL Server vagy az Azure SQL Database számára. Az Always Encrypted-kompatibilis illesztőprogramok, például az SQL ServerHez készült Microsoft JDBC Driver 6.0 (vagy újabb) ezt a viselkedést úgy érik el, hogy transzparensen titkosítják és visszafejtik a bizalmas adatokat az ügyfélalkalmazásban. Az illesztőprogram kitalálja, hogy mely lekérdezési paraméterek felelnek meg az Always Encrypted adatbázisoszlopainak, és titkosítja ezeknek a paramétereknek az értékeit, mielőtt elküldi őket az adatbázisnak. Hasonlóképpen, az illesztőprogram transzparensen visszafejti a titkosított adatbázis oszlopaiból lekért adatokat a lekérdezési eredményekben. További információ: Always Encrypted (Adatbázismotor) és Always Encrypted API-referencia a JDBC-illesztőhöz.

Előfeltételek

  • Győződjön meg arról, hogy az SQL Serverhez készült Microsoft JDBC Driver 6.0 (vagy újabb) telepítve van a fejlesztői gépen.
  • Töltse le és telepítse a Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction házirend fájlokat. Mindenképpen olvassa el a zip-fájlban található readme fájlt a telepítési utasításokhoz, valamint a lehetséges exportálási vagy importálási problémákra vonatkozó részleteket.
    • Mssql-jdbc-X.X.X.jre7.jar vagy sqljdbc41.jar esetén a házirend-fájlok letölthetők a Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7-ből.
    • Mssql-jdbc-X.X.X.jre8.jar vagy sqljdbc42.jar esetén a szabályzatfájlok letölthetők a Java titkosítási bővítményből (JCE) Korlátlan erősségű joghatósági szabályzatfájlok 8 Letöltés
    • A JRE 9-es vagy újabb verziójához (például mssql-jdbc-X.X.X.jre9.jar) nem kell letölteni a szabályzatfájlt. A Java 9 és újabb verzióban a joghatósági szabályzat alapértelmezés szerint korlátlan erősségű titkosítást biztosít.

Az oszlop főkulcs-tárolóinak használata

A titkosított oszlopok adatainak titkosításához vagy visszafejtéséhez az SQL Server oszloptitkosítási kulcsokat tart fenn. Az oszloptitkosítási kulcsok titkosított formában vannak tárolva az adatbázis metaadataiban. Minden oszlop titkosítási kulcshoz tartozik egy oszloptörzs kulcs, amely az oszlop titkosítási kulcs titkosítására szolgál.

Az adatbázis metaadatai nem tartalmazzák az oszlop főkulcsait. Ezeket a kulcsokat csak az ügyfél tartja. Az adatbázis metaadatai azonban tartalmaznak információkat arról, hogy hol vannak tárolva az oszlop főkulcsai az ügyfélhez képest. Az adatbázis metaadatai például azt mondhatják, hogy az oszlop főkulcsát tartalmazó kulcstár a Windows Tanúsítványtároló, a titkosításhoz és visszafejtéshez használt tanúsítvány pedig a Windows tanúsítványtároló egy adott elérési útján található.

Ha az ügyfél hozzáfér a tanúsítványhoz a Windows Tanúsítványtárolóban, beszerezheti a tanúsítványt. A tanúsítvány ezután használható az oszloptitkosítási kulcs visszafejtéséhez. Ezután ez a titkosítási kulcs használható az adott oszloptitkosítási kulcsot használó titkosított oszlopok adatainak visszafejtésére vagy titkosítására.

Az SQL Serverhez készült Microsoft JDBC-illesztő az oszlop főkulcsot tároló szolgáltatót használó kulcstárolóval kommunikál, amely egy osztály egy példánya, amelyből SQLServerColumnEncryptionKeyStoreProvider származik.

Használjon beépített oszlop főkulcstároló-szolgáltatókat

Az SQL Serverhez készült JDBC-illesztő tartalmazza a következő beépített oszlop-főkulcstároló-szolgáltatókat. Ezen szolgáltatók némelyike előre regisztrálva van a megadott szolgáltatónevekkel (a szolgáltató keresésére szolgál), és némelyikhez további hitelesítő adatokra vagy explicit regisztrációra van szükség.

Osztály Leírás Szolgáltató (keresési) neve Előre regisztrálva van? Plattform
SQLServerColumnEncryptionAzureKeyVaultProvider Az Azure Key Vault kulcstárolójának szolgáltatója. AZURE_KEY_VAULT A JDBC-illesztő 7.4.1-es verziója előtt nem, de a JDBC-illesztőprogram 7.4.1-es verziójától igen. Windows, Linux, macOS
SQLServerColumnEncryptionCertificateStoreProvider A Windows Tanúsítványtároló szolgáltatója. MSSQL_TANÚSÍTVÁNY_TÁR Igen Windows
SQLServerColumnEncryptionJavaKeyStoreProvider A Java-kulcstár szolgáltatója. MSSQL_JAVA_KEYSTORE Igen Windows, Linux, macOS

Az előre regisztrált kulcstár-szolgáltatók esetében nincs szükség alkalmazáskód-módosításokra ezeknek a szolgáltatóknak a használatához, de jegyezze fel a következő elemeket:

  • Győződjön meg arról, hogy az oszlop főkulcsának metaadataiban konfigurált szolgáltatónév helyes, az oszlop főkulcsának elérési útja pedig az adott szolgáltatóra érvényes kulcsútvonal-formátumot követi. Javasoljuk, hogy a kulcsokat olyan eszközökkel konfigurálja, mint az SQL Server Management Studio, amely automatikusan létrehozza az érvényes szolgáltatóneveket és kulcsútvonalakat a CREATE COLUMN MASTER KEY (Transact-SQL) utasítás kiadásához.
  • Győződjön meg arról, hogy az alkalmazás hozzáfér a kulcshoz a kulcstárban. Ez a feladat magában foglalhatja az alkalmazás hozzáférésének biztosítását a kulcshoz és/vagy a kulcstárhoz. A kulcstártól függően ez más kulcstárspecifikus konfigurációs lépéseket is magában foglalhat. Például a SQLServerColumnEncryptionJavaKeyStoreProvider használatához meg kell adnia a kulcstár helyét és jelszavát a kapcsolat tulajdonságai között.

Ezeket a kulcstár-szolgáltatókat az alábbi szakaszok részletesebben ismertetik. Az Always Encrypted használatához csak egy kulcstárszolgáltatót kell implementálnia.

Az Azure Key Vault-szolgáltató használata

Az Azure Key Vault egy kényelmes lehetőség az Always Encrypted oszlop-főkulcsainak tárolására és kezelésére (különösen akkor, ha az alkalmazás az Azure-ban üzemel). Az SQL ServerHez készült Microsoft JDBC-illesztőprogram beépített szolgáltatót tartalmaz az SQLServerColumnEncryptionAzureKeyVaultProviderAzure Key Vaultban tárolt kulcsokkal rendelkező alkalmazásokhoz. A szolgáltató neve AZURE_KEY_VAULT.

Megjegyzés:

A JDBC-illesztőprogramba beépített Azure Key Vault-szolgáltató támogatja az Azure Key Vault tárolóit és felügyelt HSM-eit is.

Az Azure Key Vault-tároló szolgáltatójának használatához az alkalmazásfejlesztőnek létre kell hoznia a tárolót és a kulcsokat az Azure Key Vaultban, és létre kell hoznia egy alkalmazásregisztrációt a Microsoft Entra-azonosítóban (korábbi nevén Azure Active Directory). A regisztrált alkalmazásnak Get, Decrypt, Encrypt, Unwrap Key, Wrap Key és Verify engedélyeket kell kapnia az Always Encrypted használatával létrehozott kulcstartóhoz definiált hozzáférési szabályzatokban. A kulcstartó beállításával és az oszlop főkulcsának létrehozásával kapcsolatos további információkért lásd: Azure Key Vault – Lépésről lépésre és oszlop-főkulcsok létrehozása az Azure Key Vaultban.

Az Azure Key Vault-szolgáltató esetében a JDBC-illesztő ellenőrzi az oszlop főkulcsának elérési útját a megbízható végpontok listájában. A 8.2.2-es verziótól ez a lista konfigurálható: hozzon létre egy mssql-jdbc.properties fájlt az alkalmazás munkakönyvtárában, állítsa be a AKVTrustedEndpoints tulajdonságot pontosvesszővel tagolt listára. Ha az érték pontosvesszővel kezdődik, kiterjeszti az alapértelmezett listát. Ellenkező esetben lecseréli az alapértelmezett listát.

Az alapértelmezett, megbízható végpontok a következők:

  • *vault.azure.net
  • *vault.azure.cn
  • *vault.usgovcloudapi.net
  • *vault.microsoftazure.de
  • *managedhsm.azure.net (v9.2+)
  • *managedhsm.azure.cn (v9.2+)
  • *managedhsm.usgovcloudapi.net (v9.2+)
  • *managedhsm.microsoftazure.de (v9.2+)

Az ezen a lapon szereplő példák esetében, ha létrehozott egy Azure Key Vault-alapú oszlop-főkulcsot és oszloptitkosítási kulcsot az SQL Server Management Studióval, az újra létrehozni kívánt T-SQL-szkript a saját KEY_PATH ésENCRYPTED_VALUE a példához hasonlóan nézhet ki:

CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
    KEY_STORE_PROVIDER_NAME = N'AZURE_KEY_VAULT',
    KEY_PATH = N'https://<MyKeyVaultName>.vault.azure.net:443/keys/Always-Encrypted-Auto1/c61f01860f37302457fa512bb7e7f4e8'
);

CREATE COLUMN ENCRYPTION KEY [MyCEK]
WITH VALUES
(
    COLUMN_MASTER_KEY = [MyCMK],
    ALGORITHM = 'RSA_OAEP',
    ENCRYPTED_VALUE = 0x01BA000001680074507400700073003A002F002F006400610076006...
);

A JDBC-illesztőprogramot használó alkalmazások használhatják az Azure Key Vaultot. Az Azure Key Vault ezen használatára vonatkozó szintaxis vagy utasítások a JDBC-illesztőprogram 7.4.1-es verziójától módosultak.

JDBC-illesztő 7.4.1 vagy újabb

Ez a szakasz a JDBC-illesztőprogram 7.4.1-es vagy újabb verzióját foglalja magában.

A JDBC-illesztőprogramot használó ügyfélalkalmazás konfigurálható úgy, hogy az Azure Key Vaultot használja, ha a JDBC kapcsolati sztringben szerepelteti keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>-t.

Íme egy példa, amely egy JDBC kapcsolati sztringben adja meg ezt a konfigurációs információt.

String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;user=<user>;password=<password>;columnEncryptionSetting=Enabled;keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey>";

A JDBC-illesztő automatikusan példányosít egy SQLServerColumnEncryptionAzureKeyVaultProvider objektumot, ha ezek a hitelesítő adatok megtalálhatók a kapcsolat tulajdonságai között.

Fontos

A kapcsolat tulajdonságai keyVaultProviderClientId és keyVaultProviderClientKey elavultak a 8.4.1-s verziótól. A felhasználókat javasoljuk, hogy használjákkeyStoreAuthenticationKeyStorePrincipalId, és KeyStoreSecret helyette.

JDBC-illesztőverziók a 7.4.1 előtt

Ez a szakasz a JDBC-illesztőprogramok 7.4.1 előtti verzióit foglalja magában.

A JDBC-illesztőprogramot használó ügyfélalkalmazásnak példányosítania kell egy SQLServerColumnEncryptionAzureKeyVaultProvider objektumot, majd regisztrálnia kell az objektumot az illesztőprogrammal.

SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);

clientID Egy Alkalmazásregisztráció alkalmazásazonosítója egy Microsoft Entra-bérlőben. clientKey az alkalmazás alatt regisztrált kulcsjelszó, amely API-hozzáférést biztosít az Azure Key Vaulthoz.

Miután az alkalmazás létrehozott egy példányt SQLServerColumnEncryptionAzureKeyVaultProvider, az alkalmazásnak regisztrálnia kell a példányt az illesztőprogrammal a SQLServerConnection.registerColumnEncryptionKeyStoreProviders() metódussal. Erősen ajánlott, hogy a példány az alapértelmezett keresési névvel legyen regisztrálva, AZURE_KEY_VAULT, amely beszerezhető az SQLServerColumnEncryptionAzureKeyVaultProvider.getName() API által. Az alapértelmezett név lehetővé teszi az olyan eszközök használatát, mint az SQL Server Management Studio vagy a PowerShell az Always Encrypted kulcsok kiépítéséhez és kezeléséhez (az eszközök az alapértelmezett nevet használják a metaadat-objektum oszlop főkulcsához való létrehozásához). Az alábbi példa az Azure Key Vault-szolgáltató regisztrálását mutatja be. A módszerről további információt a SQLServerConnection.registerColumnEncryptionKeyStoreProviders()JDBC-illesztőprogram Always Encrypted API-referenciája tartalmaz.

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

Fontos

Ha az Azure Key Vault kulcstároló-szolgáltatóját használja, a JDBC-illesztőprogram Azure Key Vault-implementációja függőségekkel rendelkezik ezektől a kódtáraktól (a GitHubról), amelyeket az alkalmazásnak tartalmaznia kell:

azure-sdk-for-java

microsoft-authentication-library-for-java kódtárak

A függőségek Maven-projektbe való belefoglalására vonatkozó példa: MSAL4J- és AKV-függőségek letöltése az Apache Mavennel

Azure Key Vault-hitelesítés használata felügyelt identitásokkal

A JDBC Driver 8.4.1-től az illesztőprogram támogatást adott a felügyelt identitásokkal rendelkező Azure Key Vaultokhoz való hitelesítéshez.

Felügyelt identitásokkal hitelesítheti magát az Azure Key Vaultban, ha az alkalmazás az Azure-ban van üzemeltetve. Így nem szükséges megadni és elérhetővé tenni a kódban szereplő hitelesítő adatokat.

A Key Vault felügyelt identitásokkal történő hitelesítésének kapcsolati tulajdonságai

A JDBC Driver 8.4.1 és újabb verziói esetében az illesztőprogram a következő kapcsolati tulajdonságokat vezette be:

KapcsolatTulajdonság Lehetséges értékpárosítás 1 Lehetséges értékpárosítás 2 Lehetséges értékpárosítás 3
kulcstárhitelesítés KeyVaultClientSecret KeyVaultManagedIdentity JavaKeyStorePassword
kulcstárolóFőAzonosító <Microsoft Entra alkalmazásügyfél azonosítója> <Microsoft Entra-alkalmazás objektumazonosítója> (nem kötelező) nincs adat
kulcstár titok <Microsoft Entra alkalmazás ügyfélkódja> nincs adat <titkos kód/jelszó a Java-kulcstárolóhoz>

Az alábbi példák bemutatják, hogyan használják a kapcsolati tulajdonságokat egy kapcsolati sztringben.

Felügyelt identitás használata az AKV-hitelesítéshez

"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;"

Felügyelt identitás és a fő azonosító használata az AKV hitelesítéséhez

"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;keyStorePrincipal=<principalId>"

A clientId és a clientSecret használata az AKV-hitelesítéshez

"jdbc:sqlserver://<server>:<port>;encrypt=true;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultClientSecret;keyStorePrincipalId=<clientId>;keyStoreSecret=<clientSecret>"

A felhasználókat arra javasoljuk, hogy ezeket a kapcsolati tulajdonságokat használva határozzák meg a kulcstárolókhoz használt hitelesítés típusát az SQLServerColumnEncryptionAzureKeyVaultProvider API helyett.

A korábban hozzáadott kapcsolati tulajdonságok keyVaultProviderClientIdkeyVaultProviderClientKey elavultak, és a korábban ismertetett kapcsolati tulajdonságok váltják fel.

A felügyelt identitások konfigurálásáról további információt az Azure-erőforrások felügyelt identitásainak konfigurálása virtuális gépen az Azure Portal használatával című témakörben talál.

Windows tanúsítványtároló-szolgáltató használata

A SQLServerColumnEncryptionCertificateStoreProvider használható oszlopfőkulcsok tárolására a Windows tanúsítványtárolóban. Az SQL Server Management Studio (SSMS) Always Encrypted varázslóval vagy más támogatott eszközökkel hozhatja létre az oszlop főkulcs- és oszloptitkosítási kulcsdefinícióit az adatbázisban. Ugyanez a varázsló használható önaláírt tanúsítvány létrehozásához a Windows Tanúsítványtárolóban, amely az Always Encrypted-adatok oszlop-főkulcsaként használható. Az oszlop főkulcs és az oszloptitkosítási kulcs T-SQL szintaxisával kapcsolatos további információk megtalálhatók a CREATE COLUMN MASTER KEY és CREATE COLUMN ENCRYPTION KEY című témakörben.

A SQLServerColumnEncryptionCertificateStoreProvider neve MSSQL_CERTIFICATE_STORE, és a szolgáltató objektum getName() API-jával lekérdezhető. Az illesztőprogram automatikusan regisztrálja, és zökkenőmentesen használható alkalmazásmódosítás nélkül.

Az ezen a lapon szereplő példák esetében, ha Windows tanúsítványtárolón alapuló oszlop-főkulcsot és oszloptitkosítási kulcsot hozott létre az SQL Server Management Studióval, a T-SQL-szkript az újrateremtésükhöz így nézhet ki, saját konkrét KEY_PATH és ENCRYPTED_VALUE értékekkel:

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...
);

Fontos

Bár a cikkben szereplő többi kulcstár-szolgáltató az illesztőprogram által támogatott összes platformon elérhető, a SQLServerColumnEncryptionCertificateStoreProvider JDBC-illesztőprogram implementálása csak Windows operációs rendszereken érhető el. Az mssql-jdbc_auth-<version>-<arch>.dll, ami elérhető az illesztőprogram-csomagban, függőségként van jelen. A szolgáltató használatához másolja a mssql-jdbc_auth-<version>-<arch>.dll fájlt a Windows rendszerútvonal egyik könyvtárába azon a számítógépen, amelyen a JDBC-illesztőprogram telepítve van. Másik lehetőségként beállíthatja a java.library.path rendszertulajdonságot a mssql-jdbc_auth-<version>-<arch>.dll könyvtár megadásához. Ha 32 bites Java virtuális gépet (JVM) futtat, használja a mssql-jdbc_auth-<version>-x86.dll fájlt az x86 mappában, még akkor is, ha az operációs rendszer az x64-es verzió. Ha 64 bites JVM-et futtat egy x64 processzoron, használja a fájlt az mssql-jdbc_auth-<version>-x64.dll x64 mappában. Ha például a 32 bites JVM-et használja, és a JDBC-illesztő telepítve van az alapértelmezett könyvtárban, a Java-alkalmazás indításakor megadhatja a DLL helyét a következő virtuális gép (VM) argumentummal: -Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86

Java-kulcstároló-szolgáltató használata

A JDBC-illesztő beépített kulcstár-szolgáltatói implementációval rendelkezik a Java Key Store-hoz. Ha a keyStoreAuthentication kapcsolati sztring tulajdonság megtalálható a kapcsolati sztringben, és az értéke be van állítva JavaKeyStorePassword, az illesztőprogram automatikusan példányosítja és regisztrálja a Szolgáltatót a Java Key Store-hoz. A Java-kulcstároló-szolgáltató neve MSSQL_JAVA_KEYSTORE. Ezt a nevet az API is lekérdezheti SQLServerColumnEncryptionJavaKeyStoreProvider.getName() .

Három kapcsolati sztringtulajdonság teszi lehetővé, hogy az ügyfélalkalmazás megadja az illesztőprogram által a Java-kulcstárolóban való hitelesítéshez szükséges hitelesítő adatokat. Az illesztőprogram inicializálja a szolgáltatót a kapcsolati sztringben szereplő három tulajdonság értékei alapján.

keyStoreAuthentication: A használni kívánt Java-kulcstárolót azonosítja. Az SQL Serverhez készült Microsoft JDBC Driver 6.0-s és újabb verziójával csak ezen a tulajdonságon keresztül végezhet hitelesítést a Java Key Store-ban. A Java-kulcstároló esetében ennek a tulajdonságnak az értéke legyen JavaKeyStorePassword.

keyStoreLocation: Az oszlop főkulcsát tároló Java Key Store-fájl elérési útja. Az elérési út tartalmazza a kulcstár fájlnevét.

keyStoreSecret: A kulcstárhoz és a kulcshoz használandó titkos kód/jelszó. A Java-kulcstároló használatához a kulcstárnak és a kulcs jelszavának meg kell egyeznie.

Íme egy példa az alábbi hitelesítő adatok megadására a kapcsolati sztringben:

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

Ezeket a beállításokat az objektummal is lekérheti vagy beállíthatja SQLServerDataSource . További információ: Always Encrypted API-referencia a JDBC-illesztőprogramhoz.

A JDBC-illesztő automatikusan példányosítja a SQLServerColumnEncryptionJavaKeyStoreProvider-t, ha ezek a hitelesítő adatok megtalálhatók a kapcsolat tulajdonságai között.

Oszlop főkulcsának létrehozása a Java Key Store-hoz

Ez SQLServerColumnEncryptionJavaKeyStoreProvider használható JKS- vagy PKCS12-kulcstártípusokkal. A szolgáltatóhoz használandó kulcs létrehozásához vagy importálásához használja a Java keytool segédprogramot. A kulcsnak ugyanazzal a jelszóval kell rendelkeznie, mint magának a kulcstárnak. Íme egy példa arra, hogyan hozhat létre nyilvános kulcsot és annak társított titkos kulcsát a keytool segédprogrammal. Cserélje le a <password> érvényes jelszóra.

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

Ez a parancs létrehoz egy nyilvános kulcsot, és egy X.509 önaláírt tanúsítványba csomagolja, amelyet a rendszer a kulcstárban keystore.jks tárol a társított titkos kulccsal együtt. Ezt a bejegyzést a kulcstárban az alias AlwaysEncryptedKeyazonosítja.

Íme egy példa a PKCS12-tárolótípusra. Cserélje le a <password> érvényes jelszóra.

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

Ha a kulcstároló PKCS12 típusú, a kulcskezelő segédprogram nem kér kulcsjelszót, és a kulcsjelszót meg kell adni a -keypass opcióval, mivel a SQLServerColumnEncryptionJavaKeyStoreProvider megköveteli, hogy a kulcstároló és a kulcs ugyanazt a jelszót használja.

A Windows tanúsítványtárolóból exportálhat egy tanúsítványt .pfx formátumban, és használhatja azt a SQLServerColumnEncryptionJavaKeyStoreProvider. Az exportált tanúsítvány JKS-kulcstároló-típusként is importálható a Java Key Store-ba.

A kulcstool-bejegyzés létrehozása után hozza létre az oszlop főkulcsának metaadatait az adatbázisban, amelynek szüksége van a kulcstár szolgáltatójának nevére és a kulcs elérési útjára. További információ az oszlop főkulcs metaadatainak létrehozásáról: CREATE COLUMN MASTER KEY. A SQLServerColumnEncryptionJavaKeyStoreProvider kulcs elérési útja egyszerűen a kulcs aliasa, az SQLServerColumnEncryptionJavaKeyStoreProvider neve pedig MSSQL_JAVA_KEYSTORE. Ezt a nevet az getName() osztály nyilvános API-jával SQLServerColumnEncryptionJavaKeyStoreProvider is lekérdezheti.

Az oszlop főkulcsának létrehozásához szükséges T-SQL szintaxis a következő:

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

A korábban létrehozott AlwaysEncryptedKey esetében az oszlop főkulcsdefiníciója a következő:

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

Megjegyzés:

A beépített SQL Server Management Studio funkció nem tud oszlop főkulcsdefiníciókat létrehozni a Java Key Store-hoz. A T-SQL-parancsokat programozott módon kell használni.

Oszloptitkosítási kulcs létrehozása a Java Key Store-hoz

Az SQL Server Management Studio vagy bármely más eszköz nem használható oszloptitkosítási kulcsok létrehozására a Java Key Store-ban található oszloptitkosítási kulcsok használatával. Az ügyfélalkalmazásnak programozott módon kell létrehoznia az oszloptitkosítási kulcsot az SQLServerColumnEncryptionJavaKeyStoreProvider osztálysal. További információ: Az oszlop főkulcstároló-szolgáltatóinak használata programozott kulcskiépítéshez.

Egyéni oszlop főkulcstároló-szolgáltató implementálása

Ha olyan kulcstárban szeretné tárolni az oszlop főkulcsait, amelyet egy meglévő szolgáltató nem támogat, egyéni szolgáltatót is implementálhat az SQLServerColumnEncryptionKeyStoreProvider osztály kibővítésével és a szolgáltató regisztrálásával az alábbi módszerek egyikével:

  • SQLServerConnection.registerColumnEncryptionKeyStoreProviders
  • SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection (Hozzáadva a JDBC 10.2-es verziójához)
  • SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement (Hozzáadva a JDBC 10.2-es verziójához)
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
    }
}

Regisztrálja a szolgáltatót a következővel SQLServerConnection.registerColumnEncryptionKeyStoreProviders:

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

Oszloptitkosítási kulcs gyorsítótárának elsőbbsége

Ez a szakasz a JDBC-illesztőprogram 10.2-es és újabb verziójára vonatkozik.

A kapcsolat- vagy utasításpéldányon regisztrált egyéni kulcstároló-szolgáltatók által visszafejtett oszloptitkosítási kulcsokat (CEK) az SQL Server Microsoft JDBC-illesztőprogramja nem gyorsítótárazza. Az egyéni kulcstároló-szolgáltatóknak saját CEK-gyorsítótárazási mechanizmust kell implementálniuk.

A 10.2-es verziótól a SQLServerColumnEncryptionAzureKeyVaultProvider CEK saját gyorsítótárazási implementációval rendelkezik. Amikor regisztrálva van egy kapcsolati példányon vagy utasításpéldányon, az adott SQLServerColumnEncryptionAzureKeyVaultProvider példány által visszafejtett CEK-ek felszabadulnak, amikor az példány hatókörén kívül esik.

try (SQLServerConnection conn = getConnection(); SQLServerStatement stmt = (SQLServerStatement) conn.createStatement()) {

    Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
    SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
    customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
    stmt.registerColumnEncryptionKeyStoreProvidersOnStatement(customKeyStoreProviders);
    // Perform database operation with Azure Key Vault Provider
    // Any decrypted column encryption keys will be cached              
} // Column encryption key cache of "akvProvider" is cleared when "akvProvider" goes out of scope

Megjegyzés:

Az egyéni kulcstároló-szolgáltatók által megvalósított CEK-gyorsítótárazást az illesztőprogram letiltja, ha a kulcstároló-szolgáltató példánya globálisan regisztrálva van az illesztőprogramban a SQLServerConnection.registerColumnEncryptionKeyStoreProviders módszerrel. Bármely CEK gyorsítótárazási implementációnak a CEK gyorsítótárazása előtt az élettartam időtartamára kell hivatkoznia, és nem szabad gyorsítótáraznia, ha az érték nulla. Ez elkerüli a duplikált gyorsítótárazást és a felhasználók esetleges zavarát, amikor kulcs-gyorsítótárazást próbálnak konfigurálni. A gyorsítótár élettartam-értéke a módszerrel állítható be SQLServerColumnEncryptionKeyStoreProvider.setColumnEncryptionCacheTtl .

Egyéni oszlop főkulcstároló-szolgáltató regisztrálása

Ez a szakasz a JDBC-illesztőprogram 10.2-es és újabb verziójára vonatkozik.

Az egyéni főkulcstár-szolgáltatók három különböző rétegben regisztrálhatók az illesztőprogrammal. A három regisztráció elsőbbsége a következő:

  • Ha nem üres, akkor a rendszer ellenőrzi az utasításonkénti regisztrációt.
  • Ha az utasításonkénti regisztráció üres, akkor ellenőrizzük a kapcsolatonkénti regisztrációt, feltéve, hogy az nem üres.
  • Ha a kapcsolatonkénti regisztráció üres, a rendszer ellenőrzi a globális regisztrációt.

Amint bármely kulcstároló-szolgáltatót egy regisztrációs szinten megtalálnak, a driver NEM fog visszaállni a többi regisztrációra a szolgáltató kereséséhez. Ha a szolgáltatók regisztrálva vannak, de a megfelelő szolgáltató nem található valamelyik szinten, kivétel dobódik, amely csak az ellenőrzött regisztrációban szereplő regisztrált szolgáltatókat tartalmazza.

A Windows tanúsítványtárolóhoz elérhető beépített oszlop főkulcstár-szolgáltatója előre regisztrálva van. A Microsoft Java Keystore-szolgáltató és az Azure Key Vault Keystore-szolgáltató implicit módon előre regisztrálható egy kapcsolatpéldánysal, ha a hitelesítő adatok előre meg vannak adva.

A három regisztrációs szint különböző forgatókönyveket támogat a titkosított adatok lekérdezésekor. A megfelelő módszer használatával biztosítható, hogy egy alkalmazás felhasználója hozzáférhessen az egyszerű szöveges adatokhoz. A titkosítatlan adatokhoz csak akkor fér hozzá, ha meg tudják adni a szükséges oszlop főkulcsát az oszlop főkulcsát tartalmazó kulcstároló hitelesítésével.

Az alkalmazásoknak, amelyek egy SQLServerConnection példányt osztanak meg több felhasználó között, érdemes használni a SQLServerStatement.registerColumnEncryptionKeyStoreProvidersOnStatement-et. Minden felhasználónak regisztrálnia kell egy kulcstároló-szolgáltatót egy SQLServerStatement példányon, mielőtt lekérdezést hajt végre egy titkosított oszlop eléréséhez. Ha a kulcstároló-szolgáltató hozzáfér a szükséges oszlop főkulcsához abban a kulcstárolóban, amely a felhasználó megadott hitelesítő adatait használja, a lekérdezés sikeres lesz.

Azok az alkalmazások, amelyek minden felhasználóhoz létrehoznak egy SQLServerConnection példányt, előfordulhat, hogy használni szeretnék a SQLServerConnection.registerColumnEncryptionKeyStoreProvidersOnConnection elemet. Az ezzel a módszerrel regisztrált kulcstároló-szolgáltatókat a kapcsolat használhatja a titkosított adatokat elérő lekérdezésekhez.

A regisztrált SQLServerConnection.registerColumnEncryptionKeyStoreProviders kulcstároló-szolgáltatók az alkalmazás által megadott identitást használják a kulcstárolóval való hitelesítéskor.

Az alábbi példa a kapcsolatpéldányon regisztrált egyéni oszlop főkulcstároló-szolgáltatóinak elsőbbségét mutatja be:

Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
MyCustomKeyStore myProvider = new MyCustomKeyStore();
customKeyStoreProviders.put(myProvider.getName(), myProvider);
// Registers the provider globally
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(customKeyStoreProviders);

try (SQLServerConnection conn = getConnection()) {
    customKeyStoreProviders.clear();
    SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
    customKeyStoreProviders.put(akvProvider.getName(), akvProvider);
    
    // Registers the provider on the connection
    // These providers will take precedence over globally registered providers
    conn.registerColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);              
}

Az alábbi példa a utasításpéldányon regisztrált egyéni oszlop főkulcstároló-szolgáltatóinak elsőbbségét mutatja be:

Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
MyCustomKeyStore firstProvider = new MyCustomKeyStore();
customKeyStoreProviders.put("FIRST_CUSTOM_STORE", firstProvider);
// Registers the provider globally
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(customKeyStoreProviders);

try (SQLServerConnection conn = getConnection()) {
    customKeyStoreProviders.clear();
    MyCustomKeyStore secondProvider = new MyCustomKeyStore();
    customKeyStoreProviders.put("SECOND_CUSTOM_STORE", secondProvider);    
    // Registers the provider on the connection
    conn.registerColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);

    try (SQLServerStatement stmt = (SQLServerStatement) conn.createStatement()) {
        customKeyStoreProviders.clear();
        SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
        customKeyStoreProviders.put(akvProvider.getName(), akvProvider);

        // Registers the provider on the statement
        // These providers will take precedence over connection-level providers and globally registered providers
        stmt.registerColumnEncryptionKeyStoreProvidersOnStatement(customKeyStoreProviders);
    }             
}

Az oszlop főkulcstároló szolgáltatóinak használata a programozott kulcsok biztosításához

A titkosított oszlopok eléréséhez az SQL Server Microsoft JDBC-illesztőprogramja transzparensen megkeresi és meghívja a megfelelő oszlop főkulcstároló-szolgáltatót az oszloptitkosítási kulcsok visszafejtéséhez. A normál alkalmazáskód általában nem hívja meg közvetlenül az oszlop főkulcstároló-szolgáltatóját. Az Always Encrypted-kulcsok kiépítéséhez és kezeléséhez azonban programozott módon is létrehozhat és meghívhat egy szolgáltatót. Ez a lépés lehet például egy titkosított oszloptitkosítási kulcs létrehozása és egy oszloptitkosítási kulcs visszafejtése az oszlop főkulcs-rotációjaként. További információ: Az Always Encrypted kulcskezelésének áttekintése.

Egyéni kulcstár-szolgáltató használata esetén szükség lehet a saját kulcskezelési eszközök implementálására. A Windows Tanúsítványtárolóban vagy az Azure Key Vaultban tárolt kulcsok használatához használhat meglévő eszközöket, például az SQL Server Management Studiót vagy a PowerShellt a kulcsok kezeléséhez és kiépítéséhez. A Java-kulcstárolóban tárolt kulcsok használatához programozott módon kell kiépítenie a kulcsokat. Az alábbi példa bemutatja, hogyan titkosíthatja az SQLServerColumnEncryptionJavaKeyStoreProvider osztály a kulcsot a Java-kulcstárolóban tárolt kulccsal.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerException;

/**
 * This program demonstrates how to create a column encryption key programmatically for the Java Key Store.
 */
public class AlwaysEncrypted {
    // Alias of the key stored in the keystore.
    private static String keyAlias = "<provide key alias>";

    // Name by which the column master key will be known in the database.
    private static String columnMasterKeyName = "MyCMK";

    // Name by which the column encryption key will be known in the database.
    private static String columnEncryptionKey = "MyCEK";

    // The location of the keystore.
    private static String keyStoreLocation = "C:\\Dev\\Always Encrypted\\keystore.jks";

    // The password of the keystore and the key.
    private static char[] keyStoreSecret = "<password>".toCharArray();

    /**
     * Name of the encryption algorithm used to encrypt the value of the column encryption key. The algorithm for the system providers must be
     * RSA_OAEP.
     */
    private static String algorithm = "RSA_OAEP";

    public static void main(String[] args) {
        String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";

        try (Connection connection = DriverManager.getConnection(connectionUrl);
                Statement statement = connection.createStatement();) {

            // Instantiate the Java Key Store provider.
            SQLServerColumnEncryptionKeyStoreProvider storeProvider = new SQLServerColumnEncryptionJavaKeyStoreProvider(keyStoreLocation,
                    keyStoreSecret);

            byte[] encryptedCEK = getEncryptedCEK(storeProvider);

            /**
             * Create column encryption key For more details on the syntax, see:
             * https://learn.microsoft.com/sql/t-sql/statements/create-column-encryption-key-transact-sql Encrypted column encryption key first needs
             * to be converted into varbinary_literal from bytes, for which byteArrayToHex() is used.
             */
            String createCEKSQL = "CREATE COLUMN ENCRYPTION KEY "
                    + columnEncryptionKey
                    + " WITH VALUES ( "
                    + " COLUMN_MASTER_KEY = "
                    + columnMasterKeyName
                    + " , ALGORITHM =  '"
                    + algorithm
                    + "' , ENCRYPTED_VALUE =  0x"
                    + byteArrayToHex(encryptedCEK)
                    + " ) ";
            statement.executeUpdate(createCEKSQL);
            System.out.println("Column encryption key created with name : " + columnEncryptionKey);
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static byte[] getEncryptedCEK(SQLServerColumnEncryptionKeyStoreProvider storeProvider) throws SQLServerException {
        String plainTextKey = "You need to give your plain text";

        // plainTextKey has to be 32 bytes with current algorithm supported
        byte[] plainCEK = plainTextKey.getBytes();

        // This will give us encrypted column encryption key in bytes
        byte[] encryptedCEK = storeProvider.encryptColumnEncryptionKey(keyAlias, algorithm, plainCEK);

        return encryptedCEK;
    }

    public static String byteArrayToHex(byte[] a) {
        StringBuilder sb = new StringBuilder(a.length * 2);
        for (byte b : a)
            sb.append(String.format("%02x", b).toUpperCase());
        return sb.toString();
    }
}

Az Always Encrypted engedélyezése alkalmazás-lekérdezésekhez

A paraméterek titkosításának és a titkosított oszlopok lekérdezési eredményeinek visszafejtésének legegyszerűbb módja a kapcsolati sor kulcsszavának columnEncryptionSetting értékét Enabled-ra állítani.

Az alábbi kapcsolati sztring egy példa az Always Encrypted JDBC-illesztőprogramban való engedélyezésére:

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

A következő kód egyenértékű példa az SQLServerDataSource objektum használatára:

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

Az Always Encrypted egyéni lekérdezésekhez is engedélyezhető. További információ: Az Always Encrypted teljesítményhatásának szabályozása. Az Always Encrypted engedélyezése nem elegendő a titkosítás vagy a visszafejtés sikerességéhez. Önnek is meg kell győződnie:

  • Az alkalmazás rendelkezik a VIEW ANY COLUMN MASTER KEY DEFINITION és VIEW ANY COLUMN ENCRYPTION KEY DEFINITION adatbázis-engedélyekkel, amelyek szükségesek az Always Encrypted kulcsok metadata eléréséhez az adatbázisban. További részletekért tekintse meg az Always Encrypted (adatbázismotor) engedélyeit.
  • Az alkalmazás hozzáférhet az oszlopfőkulcshoz, amely védi az oszloptitkosítási kulcsokat, amelyek a lekérdezett adatbázisoszlopokat titkosítják. A Java Key Store-szolgáltató használatához további hitelesítő adatokat kell megadnia a kapcsolati sztringben. További információ: Java Key Store-szolgáltató használata.

A java.sql.Time értékek kiszolgálóra küldésének konfigurálása

A sendTimeAsDatetime kapcsolati tulajdonság a java.sql.Time érték kiszolgálóra küldésének konfigurálására szolgál. Ha hamis értékre van állítva, a rendszer SQL Server-időtípusként küldi el az időértéket. Ha igaz értékre van állítva, a rendszer dátum/idő típusúként küldi el az időértéket. Ha egy időoszlop titkosítva van, a sendTimeAsDatetime tulajdonságnak hamisnak kell lennie, mivel a titkosított oszlopok nem támogatják az időről dátumra történő átalakítást. Azt is vegye figyelembe, hogy ez a tulajdonság alapértelmezés szerint igaz, ezért a titkosított időoszlopok használata esetén állítsa hamisra. Ellenkező esetben a vezető kivételt fog dobni. Az illesztőprogram 6.0-s verziójától kezdve az SQLServerConnection osztály két módszerrel konfigurálja a tulajdonság értékét programozott módon:

  • public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
  • nyilvános logikai getSendTimeAsDatetime()

A tulajdonságról további információt a java.sql.Time-értékek kiszolgálóra történő küldésének konfigurálása című témakörben talál.

A sztringértékek kiszolgálóra küldésének konfigurálása

A sendStringParametersAsUnicode kapcsolati tulajdonság használatával konfigurálható, hogy a sztringértékek hogyan legyenek elküldve az SQL Servernek. Ha igaz értékre van állítva, a rendszer Unicode formátumban küldi el a sztringparamétereket a kiszolgálónak. Ha hamis értékre van állítva, a sztringparaméterek Unicode helyett nem Unicode formátumban, például ASCII vagy MBCS formátumban lesznek elküldve. A tulajdonság alapértelmezett értéke igaz. Ha az Always Encrypted engedélyezve van, és egy char/varchar/varchar(max) oszlop titkosítva van, az értéknek sendStringParametersAsUnicode hamisnak kell lennie. Ha ez a tulajdonság igaz értékre van állítva, az illesztőprogram kivételt fog kivenni az adatok Unicode-karaktereket tartalmazó titkosított char/varchar/varchar(max) oszlopból való visszafejtésekor. A tulajdonságról további információt a Kapcsolat tulajdonságainak beállítása című témakörben talál.

Fontos

Ha a sendStringParametersAsUnicode be van állítva true-re, és Unicode-adatok kerülnek beillesztésre egy Always Encrypted titkosítással ellátott char/varchar oszlopba, adatvesztés fordulhat elő hiba jelentése nélkül. Az adatvesztés csak akkor észlelhető, ha a kiszolgálóról való visszaolvasás után próbálja visszafejteni az adatokat. Az eredmény egy Decryption failed. The last 10 bytes of the encrypted column encryption key are: 'C3-D9-10-4E-C1-45-8B-94-A2-43'. The first 10 bytes of ciphertext are: '01-9B-9D-A6-3E-40-22-53-15-9B'. hiba lehet.

Fontos, hogy a megfelelő oszlopadattípusokat használja, és a titkosított adatok beszúrásakor adja meg a paraméterek megfelelő adattípusát. Ha Unicode-adatok várhatók, használjon nchar/nvarchar oszlopokat és setNString() metódusokat. A kiszolgáló nem tud implicit adatkonvertálásokat végrehajtani, és korlátozott mértékben képes észlelni az adathibákat, ha az Always Encrypted engedélyezve van.

Adatok beolvasása és módosítása titkosított oszlopokban

Miután engedélyezte az Always Encryptedt az alkalmazás-lekérdezésekhez, szabványos JDBC API-k használatával lekérheti vagy módosíthatja az adatokat titkosított adatbázisoszlopokban. Ha az alkalmazás rendelkezik a szükséges adatbázis-engedélyekkel, és hozzáfér az oszlop főkulcsához, az illesztő titkosítja a titkosított oszlopokat célzó lekérdezési paramétereket, és visszafejti a titkosított oszlopokból lekért adatokat.

Ha az Always Encrypted nincs engedélyezve, a titkosított oszlopokat megcélzott paraméterekkel rendelkező lekérdezések sikertelenek lesznek. A lekérdezések továbbra is lekérhetik az adatokat a titkosított oszlopokból, amíg a lekérdezés nem tartalmaz titkosított oszlopokat célzó paramétereket. Az illesztőprogram azonban nem kísérli meg visszafejteni a titkosított oszlopokból lekért értékeket, és az alkalmazás binárisan titkosított adatokat (bájttömbökként) fog kapni.

Az alábbi táblázat a lekérdezések viselkedését foglalja össze attól függően, hogy az Always Encrypted engedélyezve van-e vagy sem:

Lekérdezési jellemző Az Always Encrypted engedélyezve van, és az alkalmazás hozzáférhet a kulcsokhoz és a kulcs metaadataihoz Az Always Encrypted engedélyezve van, és az alkalmazás nem tudja elérni a kulcsokat vagy a kulcs metaadatait Az Always Encrypted funkció le van tiltva
Titkosított oszlopokat célzó paraméterekkel rendelkező lekérdezések. A paraméterértékek transzparensen titkosítva vannak. Hiba Hiba
Titkosított oszlopokból adatokat lekérdező lekérdezések a titkosított oszlopokat célzó paraméterek nélkül. A titkosított oszlopok eredményei transzparensen visszafejthetők. Az alkalmazás megkapja a titkosított oszlopokhoz konfigurált SQL Server-típusoknak megfelelő JDBC-adattípusok egyszerű szöveges értékeit. Hiba A titkosított oszlopok eredményei nem lesznek visszafejtve. Az alkalmazás bájttömbökként (bájt[]) fogadja a titkosított értékeket.

Titkosított adat példák beszúrása és beolvasása

Az alábbi példák az adatok titkosított oszlopokban való beolvasását és módosítását szemléltetik. A példák a következő sémával és titkosított SSN- és BirthDate-oszlopokkal rendelkező céltáblát feltételezik. Ha "MyCMK" nevű oszloptitkosítási kulcsot és "MyCEK" nevű oszloptitkosítási kulcsot konfigurált (az előző kulcstár-szolgáltatók szakaszaiban leírtak szerint), a következő szkripttel hozhatja létre a táblát:

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

Minden Java-példakódhoz be kell szúrnia a keystore-specifikus kódot a feljegyzett helyre.

Azure Key Vault-kulcstároló-szolgáltató használata:

    String clientID = "<Azure Application ID>";
    String clientKey = "<Azure Application API Key Password>";
    SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientID, clientKey);
    Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
    keyStoreMap.put(akvProvider.getName(), akvProvider);
    SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
    String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<databaseName>;user=<user>;password=<password>;columnEncryptionSetting=Enabled;";

Windows Tanúsítványtár kulcstár-szolgáltató használata:

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

Java Key Store-kulcstár-szolgáltató használata:

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

Az adatok beszúrásának példája

Ez a példa beszúr egy sort a Betegek táblába. Jegyezze fel a következő elemeket:

  • A mintakód nem tartalmaz titkosítást. Az SQL Server Microsoft JDBC-illesztőprogramja automatikusan észleli és titkosítja a titkosított oszlopokat célzó paramétereket. Ez a viselkedés transzparenssé teszi a titkosítást az alkalmazás számára.
  • Az adatbázisoszlopokba beszúrt értékek, beleértve a titkosított oszlopokat is, paraméterként SQLServerPreparedStatementlesznek átadva. Bár a paraméterek nem kötelezőek, amikor nem titkosított oszlopokba küldenek értékeket (bár erősen ajánlott, mert segít megelőzni az SQL-injektálást), a titkosított oszlopokat megcélzó értékekhez szükséges. Ha a titkosított oszlopokba beszúrt értékek a lekérdezési utasításba beágyazott literálként lettek átadva, a lekérdezés meghiúsulna, mert az illesztőprogram nem tudná meghatározni a célként megadott titkosított oszlopok értékeit, és nem titkosítaná az értékeket. Ennek eredményeképpen a kiszolgáló elutasítja őket, mivel nem kompatibilisek a titkosított oszlopokkal.
  • A program által kinyomtatott összes érték egyszerű szöveges lesz, mivel az SQL Server Microsoft JDBC-illesztőprogramja transzparensen visszafejti a titkosított oszlopokból lekért adatokat.
  • Ha WHERE záradékkal végez kereséseket, a WHERE záradékban használt értéket paraméterként kell átadni, hogy az illesztőprogram transzparensen titkosíthassa azt, mielőtt elküldené az adatbázisba. A következő példában az SSN paraméterként lesz átadva, a LastName viszont konstansként lesz átadva, mivel a LastName nincs titkosítva.
  • Az SSN-oszlopot megcélzó paraméter beállítási metódusa az setString()char/varchar SQL Server adattípusának megfelel. Ha ennél a paraméternél a setNString() beállító metódust használták, amely a nchar/nvarchar-ra térképez, akkor a lekérdezés meghiúsul, mivel az Always Encrypted nem támogatja a konverziót titkosított nchar/nvarchar értékekről titkosított char/varchar értékekre.
// <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();
}

Egyszerű szöveges adatok beolvasása – példa

Az alábbi példa bemutatja az adatok titkosított értékeken alapuló szűrését és egyszerű szöveges adatok titkosított oszlopokból való lekérését. Jegyezze fel a következő elemeket:

  • A WHERE záradékban az SSN-oszlopra való szűréshez használt értéket paraméterként kell átadni, hogy a SQL Serverhez készült Microsoft JDBC-illesztő átláthatóan titkosíthassa, mielőtt elküldené az adatbázisnak.
  • A program által kinyomtatott összes érték egyszerű szöveges lesz, mivel az SQL Server Microsoft JDBC-illesztőprogramja transzparensen visszafejti az SSN- és BirthDate-oszlopokból lekért adatokat.

Megjegyzés:

ha az oszlopok determinisztikus titkosítással vannak titkosítva, a lekérdezések egyenlőségi összehasonlításokat végezhetnek rajtuk. További információ: determinisztikus titkosítás.

// <Insert keystore-specific code here>
try (Connection connection = DriverManager.getConnection(connectionUrl);
        PreparedStatement selectStatement = connection
                .prepareStatement("\"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN = ?;\"");) {
    selectStatement.setString(1, "795-73-9838");
    ResultSet rs = selectStatement.executeQuery();
    while (rs.next()) {
        System.out.println("SSN: " + rs.getString("SSN") + ", FirstName: " + rs.getString("FirstName") + ", LastName:"
                + rs.getString("LastName") + ", Date of Birth: " + rs.getString("BirthDate"));
    }
}
// Handle any errors that may have occurred.
catch (SQLException e) {
    e.printStackTrace();
}

Példa titkosított adatok beolvasására

Ha az Always Encrypted nincs engedélyezve, a lekérdezések továbbra is lekérhetik az adatokat titkosított oszlopokból, feltéve, hogy a lekérdezés nem tartalmaz titkosított oszlopokat célzó paramétereket.

Az alábbi példa a bináris titkosított adatok titkosított oszlopokból való lekérését mutatja be. Jegyezze fel a következő elemeket:

  • Mivel az Always Encrypted nincs engedélyezve a kapcsolati sztringben, a lekérdezés az SSN és a BirthDate titkosított értékeit adja vissza bájttömbökként (a program sztringekké alakítja az értékeket).
  • Az Always Encrypted letiltott titkosított oszlopaiból adatokat lekérő lekérdezésnek lehetnek paraméterei, feltéve, hogy egyik paraméter sem céloz meg titkosított oszlopot. A következő lekérdezés a LastName szerint szűr, amely nincs titkosítva az adatbázisban. Ha a lekérdezésT SSN vagy BirthDate szűri, a lekérdezés sikertelen lesz.
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();
}

A titkosított oszlopok lekérdezésével kapcsolatos gyakori problémák elkerülése

Ez a szakasz a Java-alkalmazásokból származó titkosított oszlopok lekérdezése során előforduló gyakori hibakategóriákat, valamint néhány, az elkerülésükre vonatkozó útmutatást ismerteti.

Nem támogatott adattípus-konverziós hibák

Az Always Encrypted kevés konverziót támogat a titkosított adattípusokhoz. A támogatott típuskonverziók részletes listáját az Always Encrypted (adatbázismotor) című témakörben találja. Az alábbiakban bemutatjuk, hogyan kerülheti el az adattípus-konverziós hibákat. Ellenőrizze a következőket:

  • a titkosított oszlopokat megcélzó paraméterek értékeinek átadásakor a megfelelő beállítási módszereket kell használnia. Győződjön meg arról, hogy a paraméter SQL Server-adattípusa pontosan megegyezik a céloszlop típusával, vagy támogatott a paraméter SQL Server-adattípusának átalakítása az oszlop céltípusára. Api-metódusok lettek hozzáadva a SQLServerPreparedStatement, SQLServerCallableStatementés SQLServerResultSet osztályokhoz, hogy adott SQL Server-adattípusoknak megfelelő paramétereket adjanak át. Az új API-k teljes listáját a JDBC-illesztőprogram Always Encrypted API-referenciája tartalmazza. Ha nem felel meg az adattípus-definícióknak, valószínűleg operandus típusú ütközési hibákat fog eredményezni. Az alábbiakban néhány példát mutatunk be az Always Encrypted használatakor szükséges módosításokra:

    • A metódussal setTimestamp() paramétert adhat át egy nem titkosított datetime2 vagy datetime oszlopnak. Ha azonban egy oszlop titkosítva van, pontosan az adatbázis oszloptípusát képviselő módszert kell használnia. Az setTimestamp() értékeket egy titkosított datetime2 oszlopnak továbbítja, és setDateTime() az értékeket egy titkosított datetime oszlopnak továbbítja.
    • A metódussal setBinary() paramétert adhat át egy nem titkosított varbinary(max) vagy binary oszlopnak. Az illesztő alapértelmezés szerint a BINARY paraméterekhez a setBinary() adattípust alkalmazza, és a kiszolgáló implicit módon átalakíthatja az adatokat, hogy beilleszthesse őket egy varbinary(max) oszlopba. Ha azonban egy varbinary(max) oszlop titkosítva van, pontosabb típust kell megadnia a paraméteradatokhoz. Példa: preparedStatement.setObject(1, binaryData, java.sql.JDBCType.LONGVARBINARY)
  • a decimális és numerikus SQL Server-adattípusok oszlopait megcélzó paraméterek pontossága és mérete megegyezik a céloszlophoz konfigurált pontossági és méretezési értékekkel. Az API-metódusok hozzáadva lettek a , SQLServerPreparedStatementés SQLServerCallableStatement osztályokhoz a SQLServerResultSetpontosság és a skálázás elfogadásához, valamint a paraméterek/oszlopok adatértékeihez, amelyek decimális és numerikus adattípusokat jelölnek. Az új/túlterhelt API-k teljes listájáért tekintse meg a JDBC-illesztőprogram Always Encrypted API-referenciáját .

    • Amikor a Java BigDecimal használja paramétertípusként, amely egy adott tizedes oszlopot céloz meg az adatbázisban, meg kell adnia a pontosságot és a skálát az setBigDecimal() vagy setValue() metódushoz. A helyes pontosság és skálázás megadásának elmulasztása az alábbihoz hasonló hibát eredményezhet:
    Operand type clash: decimal(18,0) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'myCek', column_encryption_key_database_name = 'issue2169') is incompatible with decimal(20,4) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'myCek', column_encryption_key_database_name = 'myDatabase')
    
  • az SQL Server adattípusok datetime2, datetimeoffset oszlopait megcélzó paraméterek tört másodperces pontossága/méretezése nem lehet nagyobb, mint a céloszlop tört másodperces pontossága/méretezése azokban a lekérdezésekben, amelyek a céloszlop értékeit módosítják. Az API-metódusok hozzáadva lettek a , SQLServerPreparedStatementés SQLServerCallableStatement osztályokhoz, hogy elfogadják a SQLServerResultSettört másodperces pontosságot/skálázást, valamint az ilyen adattípusokat képviselő paraméterek adatértékeit. Az új/túlterhelt API-k teljes listáját lásd: Always Encrypted API-referencia a JDBC-illesztőprogramhoz.

Helytelen kapcsolattulajdonságok miatti hibák

Ez a szakasz azt ismerteti, hogyan konfigurálhatja megfelelően a kapcsolatbeállításokat az Always Encrypted-adatok használatához. Mivel a titkosított adattípusok támogatják a korlátozott konverziókat, a sendTimeAsDatetime és sendStringParametersAsUnicode csatlakozási beállítások megfelelő konfigurálása szükséges a titkosított oszlopok használatához. Ellenőrizze a következőket:

A titkosított értékek helyett egyszerű szöveg átadása miatti hibák

Minden olyan értéket, amely egy titkosított oszlopot céloz meg, titkosítva kell lennie az alkalmazásban. Egy titkosított oszlop egyszerű szöveges értéke alapján történő beszúrási/módosítási vagy szűrési kísérlet az alábbihoz hasonló hibát eredményez:

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'

Az ilyen hibák megelőzése érdekében győződjön meg arról, hogy:

  • Az Always Encrypted engedélyezve van a titkosított oszlopokat megcélzó alkalmazás-lekérdezésekhez (a kapcsolati sztringhez vagy egy adott lekérdezéshez).
  • előre elkészített utasításokat és paramétereket használva küldi el a titkosított oszlopokra irányuló adatokat. Az alábbi példa egy lekérdezést mutat be, amely helytelenül szűr egy literált/állandót használva egy titkosított oszlopon (SSN), ahelyett, hogy paraméterként adná át a literált. A lekérdezés sikertelen lesz:
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM Customers WHERE SSN='795-73-9838'");

A bemeneti paraméterek titkosításának kötelező alkalmazása

A Force Encryption funkció kikényszeríti egy paraméter titkosítását az Always Encrypted használatával. Ha kényszerített titkosítást használ, és az SQL Server tájékoztatja az illesztőprogramot, hogy a paramétert nem kell titkosítani, a paramétert használó lekérdezés sikertelen lesz. Ez a tulajdonság további védelmet nyújt az olyan biztonsági támadások ellen, amelyek egy sérült SQL Servert érintenek, amely helytelen titkosítási metaadatokat biztosít az ügyfél számára, ami adatfeltárást eredményezhet. A SQLServerPreparedStatement és SQLServerCallableStatement osztályokban lévő set* metódusok, valamint az update* osztályban található SQLServerResultSet metódusok túl vannak terhelve, hogy elfogadjanak egy logikai argumentumot az erőtitkosítási beállítás megadásához. Ha az argumentum értéke hamis, az illesztőprogram nem kényszeríti a titkosítást a paraméterekre. Ha a kényszerített titkosítás értéke igaz, a lekérdezési paraméter csak akkor lesz elküldve, ha a céloszlop titkosítva van, és az Always Encrypted engedélyezve van a kapcsolaton vagy az utasításon. Ez a tulajdonság további biztonsági réteget biztosít, biztosítva, hogy az illesztőprogram ne küldjön tévesen adatokat az SQL Servernek egyszerű szövegként, amikor az várhatóan titkosítva lesz.

Azokkal a metódusokkal kapcsolatban, amelyek az erőtitkosítási beállítással vannak túlterhelve, további információt a SQLServerPreparedStatement című témakörben találhat.

Az Always Encrypted teljesítményhatásának szabályozása

Mivel az Always Encrypted egy ügyféloldali titkosítási technológia, a teljesítményterhelés nagy része az ügyféloldalon figyelhető meg, nem az adatbázisban. A titkosítási és visszafejtési műveletek költségein kívül az ügyféloldal egyéb teljesítményterhelési forrásai a következők:

  • A lekérdezési paraméterek metaadatainak lekéréséhez kerek utakat adott hozzá az adatbázishoz.
  • Egy oszlop főkulcstárának hívása az oszlop főkulcsának eléréséhez.

Ez a szakasz az SQL ServerHez készült Microsoft JDBC-illesztő beépített teljesítményoptimalizálásait ismerteti, valamint azt, hogy hogyan szabályozható a korábban említett két tényező hatása a teljesítményre.

A visszautak szabályozása a lekérdezési paraméterek metaadatainak visszakereséséhez

Ha az Always Encrypted engedélyezve van egy kapcsolathoz, az illesztőprogram alapértelmezés szerint meghívja sys.sp_describe_parameter_encryption minden paraméteres lekérdezéshez, és átadja a lekérdezési utasítást (paraméterértékek nélkül) az adatbázisnak. sys.sp_describe_parameter_encryption elemzi a lekérdezési utasítást, hogy kiderítse, van-e szükség paraméterek titkosítására, és ha igen, mindegyiknél visszaadja a titkosítással kapcsolatos információkat, amelyek lehetővé teszik az illesztőprogram számára a paraméterértékek titkosítását. Ez a viselkedés magas szintű átláthatóságot biztosít az ügyfélalkalmazás számára. Amíg az alkalmazás paraméterekkel adja át a titkosított oszlopokat megcélozó értékeket az illesztőprogramnak, az alkalmazásnak (és az alkalmazásfejlesztőnek) nem kell tudnia, hogy mely lekérdezések férnek hozzá a titkosított oszlopokhoz.

Always Encrypted beállítása a lekérdezés szintjén

A paraméteres lekérdezések titkosítási metaadatainak lekérése teljesítményhatásának szabályozásához engedélyezheti az Always Encryptedt az egyes lekérdezésekhez a kapcsolat beállítása helyett. Így biztosítható, hogy a sys.sp_describe_parameter_encryption csak olyan lekérdezések esetén legyen meghívva, amelyekről tudja, hogy a paraméterek titkosított oszlopokat céloznak. Vegye figyelembe azonban, hogy ezzel csökkenti a titkosítás átláthatóságát: ha módosítja az adatbázisoszlopok titkosítási tulajdonságait, előfordulhat, hogy módosítania kell az alkalmazás kódját, hogy igazodjon a séma változásaihoz.

Az egyes lekérdezések Always Encrypted viselkedésének szabályozásához konfigurálnia kell az egyes utasításobjektumokat egy Enum, SQLServerStatementColumnEncryptionSetting átadásával, amely meghatározza, hogyan lesznek elküldve és fogadva az adatok az adott utasítás titkosított oszlopainak olvasása és írása során. Íme néhány hasznos irányelv:

  • Ha az ügyfélalkalmazás által küldött lekérdezések többsége egy adatbázis-kapcsolaton keresztül ér el titkosított oszlopokat, kövesse az alábbi irányelveket:

    • Állítsa a kapcsolati karakterlánc columnEncryptionSetting kulcsszót a következőre Enabled.
    • Olyan egyedi lekérdezésekhez van beállítva SQLServerStatementColumnEncryptionSetting.Disabled , amelyek nem férnek hozzá a titkosított oszlopokhoz. Ez a beállítás letiltja mind a sys.sp_describe_parameter_encryption hívását, mind az eredményhalmazban lévő értékek visszafejtését.
    • Olyan egyedi lekérdezésekhez van beállítva SQLServerStatementColumnEncryptionSetting.ResultSet , amelyek nem rendelkeznek titkosítást igénylő paraméterekkel, de titkosított oszlopokból kérnek le adatokat. Ez a beállítás letiltja a hívás- sys.sp_describe_parameter_encryption és paramétertitkosítást. A lekérdezés visszafejti az eredményeket a titkosítási oszlopokból.
  • Ha az ügyfélalkalmazás adatbázis-kapcsolaton keresztül küldött legtöbb lekérdezése nem fér hozzá a titkosított oszlopokhoz, kövesse az alábbi irányelveket:

    • Állítsa a kapcsolati karakterlánc columnEncryptionSetting kulcsszót a következőre Disabled.
    • Olyan egyedi lekérdezésekre van beállítva SQLServerStatementColumnEncryptionSetting.Enabled , amelyek rendelkeznek a titkosítandó paraméterekkel. Ez a beállítás lehetővé teszi a titkosított oszlopokból lekért lekérdezési eredmények hívását sys.sp_describe_parameter_encryption és visszafejtését is.
    • Olyan lekérdezésekhez van beállítva SQLServerStatementColumnEncryptionSetting.ResultSet , amelyek nem rendelkeznek titkosítást igénylő paraméterekkel, de titkosított oszlopokból kérnek le adatokat. Ez a beállítás letiltja a hívás- sys.sp_describe_parameter_encryption és paramétertitkosítást. A lekérdezés visszafejti az eredményeket a titkosítási oszlopokból.

A SQLServerStatementColumnEncryptionSetting beállítások nem használhatók a titkosítás megkerülésére és egyszerű szöveges adatokhoz való hozzáférésre. Az oszloptitkosítás utasításon való konfigurálásáról további információt a JDBC-illesztőprogram Always Encrypted API-referenciája című témakörben talál.

Az alábbi példában az Always Encrypted le van tiltva az adatbázis-kapcsolathoz. Az alkalmazás problémáinak lekérdezése olyan paraméterrel rendelkezik, amely a nem titkosított LastName oszlopot célozza. A lekérdezés adatokat kér le a titkosított SSN és BirthDate oszlopokból. Ilyen esetben nem szükséges meghívni sys.sp_describe_parameter_encryption a titkosítási metaadatokat. A lekérdezési eredmények visszafejtéséhez azonban engedélyezni kell, hogy az alkalmazás egyszerű szöveges értékeket fogadhasson a két titkosított oszlopból. A(z) SQLServerStatementColumnEncryptionSetting.ResultSet beállítás arra szolgál, hogy biztosítsa azt.

// Assumes the same table definition as in Section "Retrieving and modifying data in encrypted columns"
// where only SSN and BirthDate columns are encrypted in the database.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<database>;user=<user>;password=<password>;"
        + "keyStoreAuthentication=JavaKeyStorePassword;"
        + "keyStoreLocation=<keyStoreLocation>"
        + "keyStoreSecret=<keyStoreSecret>;";

String filterRecord = "SELECT FirstName, LastName, SSN, BirthDate FROM " + tableName + " WHERE LastName = ?";

try (SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionUrl);
        PreparedStatement selectStatement = connection.prepareStatement(filterRecord, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
                connection.getHoldability(), SQLServerStatementColumnEncryptionSetting.ResultSetOnly);) {

    selectStatement.setString(1, "Abel");
    ResultSet rs = selectStatement.executeQuery();
    while (rs.next()) {
        System.out.println("First name: " + rs.getString("FirstName"));
        System.out.println("Last name: " + rs.getString("LastName"));
        System.out.println("SSN: " + rs.getString("SSN"));
        System.out.println("Date of Birth: " + rs.getDate("BirthDate"));
    }
}
// Handle any errors that may have occurred.
catch (SQLException e) {
    e.printStackTrace();
}

Lekérdezési paraméter metaadatainak gyorsítótárazása

Az adatbázisra irányuló ciklikus utak számának csökkentése érdekében az SQL Server Microsoft JDBC-illesztőprogramja gyorsítótárazza a lekérdezési paraméterek titkosítással kapcsolatos adatait. A 11.2.0-s verziótól kezdve a sys.sp_describe_parameter_encryption hívásokból visszaadott paraméterek titkosítással kapcsolatos információit az illesztőprogram gyorsítótárazza, ha a társított SQL Server-folyamat nem használ biztonságos enklávékat. A biztonságos enklávék használatával történő gyorsítótárazáshoz a kiszolgálónak támogatnia kell az enklávé munkamenet újbóli létrehozását olyan esetekben, amikor a munkamenet már nem érvényes.

Oszloptitkosítási kulcs gyorsítótárazása

Az oszloptitkosítási kulcsok visszafejtéséhez az oszlop főkulcstárolójához intézett hívások számának csökkentése érdekében az SQL Server Microsoft JDBC-illesztőprogramja gyorsítótárazza az egyszerű szöveges oszloptitkosítási kulcsokat a memóriában. Miután az illesztőprogram megkapta a titkosított oszloptitkosítási kulcs értékét az adatbázis metaadataitól, az illesztőprogram először megpróbálja megtalálni a titkosított kulcs értékének megfelelő egyszerű szöveges oszloptitkosítási kulcsot. Az illesztőprogram csak akkor hívja meg az oszlop főkulcsát tartalmazó kulcstárat, ha nem találja a titkosított oszloptitkosítási kulcs értékét a gyorsítótárban.

A gyorsítótárban lévő oszloptitkosítási kulcs bejegyzéseinek élettartamértékét az API-val setColumnEncryptionKeyCacheTtl()konfigurálhatja az SQLServerConnection osztályban. A gyorsítótárban lévő oszloptitkosítási kulcs bejegyzéseinek alapértelmezett élettartamértéke két óra. A gyorsítótárazás kikapcsolásához használjon 0 értéket. Az élettartamértékek beállításához használja a következő API-t:

SQLServerConnection.setColumnEncryptionKeyCacheTtl (int columnEncryptionKeyCacheTTL, TimeUnit unit)

Ha például 10 perces élettartamértéket szeretne beállítani, használja a következőt:

SQLServerConnection.setColumnEncryptionKeyCacheTtl (10, TimeUnit.MINUTES)

Csak NAPOK, ÓRÁK, PERCek vagy MÁSODPERCek támogatottak időegységként.

Titkosított adatok másolása az SQLServerBulkCopy használatával

Ezzel a lehetőséggel SQLServerBulkCopyaz egyik táblában már titkosított és tárolt adatokat átmásolhatja egy másik táblába az adatok visszafejtése nélkül. Ehhez tegye a következőt:

  • Győződjön meg arról, hogy a céltábla titkosítási konfigurációja megegyezik a forrástábla konfigurációval. Különösen mindkét táblának ugyanazokkal az oszlopokkal kell rendelkeznie, és az oszlopokat ugyanazokkal a titkosítási típusokkal és ugyanazokkal a titkosítási kulcsokkal kell titkosítani. Ha a céloszlopok titkosítása eltér a megfelelő forrásoszloptól, a másolási művelet után nem tudja visszafejteni a céltáblában lévő adatokat. Az adatok sérültek lesznek.
  • Konfigurálja mindkét adatbázis-kapcsolatot a forrástáblához és a céltáblához anélkül, hogy engedélyezve van az Always Encrypted.
  • Adja meg a allowEncryptedValueModifications beállítást. További információ: Tömeges másolás használata a JDBC-illesztővel.

Megjegyzés:

A beállítás megadásakor AllowEncryptedValueModifications körültekintően járjon el, mert ez az adatbázis sérüléséhez vezethet, mert az SQL ServerHez készült Microsoft JDBC-illesztőprogram nem ellenőrzi, hogy az adatok valóban titkosítottak-e, vagy hogy az adatok megfelelően titkosítva van-e a céloszloptal azonos titkosítási típussal, algoritmussal és kulccsal.

Lásd még

Always Encrypted (adatbázismotor)