Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Platný pro
- Microsoft Ovladače 5.8.0 pro PHP pro SQL Server
Úvod
Funkce Always Encrypted se zabezpečenými enklávy je druhou iterací funkce Always Encrypted pro SQL Server. Funkce Always Encrypted se zabezpečenými enklávami umožňuje uživatelům provádět bohaté výpočty s šifrovanými daty vytvořením zabezpečené enklávy – oblast paměti na serveru, kde se šifrovaná data v databázi dešifrují, aby se mohly provádět výpočty. Mezi podporované operace patří porovnání a porovnávání vzorů s klauzulí LIKE .
Povolení funkce Always Encrypted se zabezpečenými enklávy
Podpora funkce Always Encrypted se zabezpečenými enklávy je dostupná v ovladačích PHP pro SQL Server počínaje verzí 5.8.0. Funkce Always Encrypted se zabezpečenými enklávy vyžaduje SQL Server 2019 nebo novější a ovladač ODBC verze 17.4 nebo novější. Obecné požadavky pro funkci Always Encrypted s ovladači PHP pro SQL Server jsou k dispozici v tématu Použití funkce Always Encrypted s ovladači PHP pro SQL Server.
Funkce Always Encrypted se zabezpečenými enklávami zajišťuje zabezpečení šifrovaných dat ověřením enklávy – to znamená ověření enklávy vůči externí službě ověření identity. Aby bylo možné používat zabezpečené enklávy, ColumnEncryption musí klíčové slovo identifikovat typ ověření identity a protokol spolu s přidruženými daty ověření identity, které jsou oddělené čárkou. Verze 17.4 ovladače ODBC podporuje pouze Virtualization-Based Security (VBS) a protokol HGS (Host Guardian Service) pro typ enklávy a protokol. Přidružená data ověření identity jsou adresa URL serveru ověření identity. Proto by se do připojovacího řetězce přidalo následující nastavení:
ColumnEncryption=VBS-HGS,http://attestationserver.mydomain/Attestation
Pokud je protokol nesprávný, ovladač ho nerozpozná, připojení selže a vrátí se chyba. Pokud je nesprávná pouze autentizační URL, připojení bude úspěšné, a při pokusu o provedení výpočtu umožněného enklávami se vyvolá chyba, ale jinak bude chování stejné jako původní chování Always Encrypted. Nastavení ColumnEncryption na enabled poskytne běžnou funkcionalitu Always Encrypted, ale pokus o operaci povolenou v enklávě vrátí chybu.
Podrobnosti o konfiguraci prostředí pro podporu funkce Always Encrypted se zabezpečenými enklávy, včetně nastavení služby Strážce hostitele a vytvoření požadovaných šifrovacích klíčů, najdete v tématu Konfigurace a použití funkce Always Encrypted se zabezpečenými enklávy.
Examples
Následující příklady, jeden pro SQLSRV a druhý pro PDO_SQLSRV, vytvoří tabulku s několika datovými typy s neskriptovaným textem, pak ji zašifrují a provedou porovnání a hledání vzorů. Všimněte si následujících podrobností:
- Při šifrování tabulky s
ALTER TABLE, pouze jeden sloupec může být zašifrován pro každé voláníALTER TABLE, takže více volání jsou vyžadována k šifrování více sloupců. - Při předávání porovnávací prahové hodnoty jako parametru pro porovnání typů char a nchar je nutné zadat šířku sloupce v odpovídající
SQLSRV_SQLTYPE_*, nebo bude vrácena chybaHY104,Invalid precision value. - Pro porovnávání vzorů musí být kolace zadána jako
Latin1_General_BIN2použitímCOLLATEpříkazu. - Při předání vzorového řetězce jako parametru pro porovnávání typů char a nchar by měl předaný parametr
SQLSRV_SQLTYPE_*nebosqlsrv_queryurčit délku řetězce,sqlsrv_preparekterý se má shodovat, a nikoli velikost sloupce, protože typy char a nchar vkládají prázdné znaky na konec řetězce. Například při porovnávání řetězce%abc%se sloupcem char(10) zadejteSQLSRV_SQLTYPE_CHAR(5). Pokud místo toho zadáteSQLSRV_SQLTYPE_CHAR(10), dotaz bude odpovídat%abc%(s pěti mezerami připojenými) a všechna data ve sloupci s méně než pěti připojenými mezerami nebudou odpovídat (takžeabcdefby neodpovídalo%abc%, protože má čtyři mezery odsazení). Pro řetězce Unicode použijtemb_strlenneboiconv_strlenfunkce k získání počtu znaků. - Rozhraní PDO neumožňuje zadat délku parametru. Místo toho zadejte délku 0 nebo
nullvPDOStatement::bindParam. Pokud je délka explicitně nastavena na jiné číslo, je parametr považován za výstupní parametr. - Porovnávání vzorů nefunguje s typy bez řetězců v funkci Always Encrypted.
- Kontrola chyb je vyloučena z důvodu přehlednosti.
Pro oba příklady jsou běžná následující data:
<?php
// Data for testing - integer, datetime2, char, nchar, varchar, and nvarchar
// String data is random, showing that we can match or compare anything
$testValues = array(array(1, "2019-12-31 01:00:00", "abcd", "㬚㔈♠既", "abcd", "㬚㔈♠既"),
array(-100, "1753-01-31 14:25:25.25", "#e@?q&zy+", "ઔܛ᎓Ե⅜", "#e@?q&zy+", "ઔܛ᎓Ե⅜"),
array(100, "2112-03-15 23:40:10.1594", "zyxwv", "㶋㘚ᐋꗡ", "zyxwv", "㶋㘚ᐋꗡ"),
array(0, "8888-08-08 08:08:08.08", "7t", "㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ", "7t", "㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ"),
);
// Queries to create the table and insert data
$createTable = "DROP TABLE IF EXISTS $myTable;
CREATE TABLE $myTable (c_integer int NULL,
c_datetime2 datetime2(7) NULL,
c_char char(32) NULL,
c_nchar nchar(32) NULL,
c_varchar varchar(32) NULL,
c_nvarchar nvarchar(32) NULL);";
$insertData = "INSERT INTO $myTable (c_integer, c_datetime2, c_char, c_nchar, c_varchar, c_nvarchar) VALUES (?, ?, ?, ?, ?, ?)";
// This is the query that encrypts the table in place
$encryptQuery = " ALTER TABLE $myTable
ALTER COLUMN [c_integer] integer
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK-enclave], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL
WITH (ONLINE = ON);
ALTER TABLE $myTable
ALTER COLUMN [c_datetime2] datetime2(7)
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK-enclave], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL
WITH (ONLINE = ON);
ALTER TABLE $myTable
ALTER COLUMN [c_char] char(32) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK-enclave], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL
WITH (ONLINE = ON);
ALTER TABLE $myTable
ALTER COLUMN [c_nchar] nchar(32) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK-enclave], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL
WITH (ONLINE = ON);
ALTER TABLE $myTable
ALTER COLUMN [c_varchar] varchar(32) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK-enclave], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL
WITH (ONLINE = ON);
ALTER TABLE $myTable
ALTER COLUMN [c_nvarchar] nvarchar(32) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK-enclave], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL
WITH (ONLINE = ON);
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;";
?>
SQLSRV
<?php
// Specify Azure Key Vault credentials using the KeyStoreAuthentication, KeyStorePrincipalId, and KeyStoreSecret keywords
// Otherwise, the local Windows Certificate Store will be used
$options = array('database'=>$myDatabase,
'uid'=>$myUsername,
'pwd'=>$myPassword,
'CharacterSet'=>'UTF-8',
'ReturnDatesAsStrings'=>true,
'ColumnEncryption'=>"VBS-HGS,http://myattestationserver.mydomain/Attestation",
);
$conn = sqlsrv_connect($myServer, $options);
// Create the table and insert the test data
$stmt = sqlsrv_query($conn, $createTable);
foreach ($testValues as $values) {
$stmt = sqlsrv_prepare($conn, $insertData, $values);
sqlsrv_execute($stmt);
}
// Encrypt the table in place
$stmt = sqlsrv_query($conn, $encryptQuery);
// Test comparison and pattern matching on the encrypted table
echo "Test comparisons:\n";
$intThreshold = 0;
$testGreater = "SELECT c_integer FROM $myTable WHERE c_integer > ?";
$param = array($intThreshold, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_INT);
$stmt = sqlsrv_prepare($conn, $testGreater, array($param));
getResults($stmt);
// Expect:
// 1
// 100
$datetimeThreshold = "3000-01-01 00:00:00.0";
$testLess = "SELECT c_datetime2 FROM $myTable WHERE c_datetime2 < ?";
$param = array($datetimeThreshold, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_DATETIME2);
$stmt = sqlsrv_prepare($conn, $testLess, array($param));
getResults($stmt);
// Expect:
// 2019-12-31 01:00:00.0000000
// 1753-01-31 14:25:25.2500000
// 2112-03-15 23:40:10.1594000
$charThreshold = "abcd";
$ncharThreshold = "㬚㔈♠既";
$testGreaterEqual = "SELECT c_char FROM $myTable WHERE c_char >= ?";
$param = array($charThreshold, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_CHAR(32));
$stmt = sqlsrv_prepare($conn, $testGreaterEqual, array($param));
getResults($stmt);
// Expect:
// abcd
// zyxwv
$testLessEqual = "SELECT c_nchar FROM $myTable WHERE c_nchar <= ?";
$param = array($ncharThreshold, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('UTF-8'), SQLSRV_SQLTYPE_NCHAR(32));
$stmt = sqlsrv_prepare($conn, $testLessEqual, array($param));
getResults($stmt);
// Expect:
// 㬚㔈♠既
// ઔܛ᎓Ե⅜
// 㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
$testNotGreater = "SELECT c_varchar FROM $myTable WHERE c_varchar !> ?";
$param = array($charThreshold, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_VARCHAR);
$stmt = sqlsrv_prepare($conn, $testNotGreater, array($param));
getResults($stmt);
// Expect:
// abcd
// #e@?q&zy+
// 7t
$testNotLess = "SELECT c_nvarchar FROM $myTable WHERE c_nvarchar !< ?";
$param = array($ncharThreshold, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('UTF-8'), SQLSRV_SQLTYPE_NVARCHAR);
$stmt = sqlsrv_prepare($conn, $testNotLess, array($param));
getResults($stmt);
// Expect:
// 㬚㔈♠既
// 㶋㘚ᐋꗡ
echo "\nTest pattern matching:\n";
$charMatch = "%zy%";
$ncharMatch = "%㔈♠既%";
$param = array($charMatch, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_CHAR(strlen($charMatch)));
$testCharMatch = "SELECT c_char FROM $myTable WHERE c_char LIKE ? COLLATE Latin1_General_BIN2";
$stmt = sqlsrv_prepare($conn, $testCharMatch, array($param));
getResults($stmt);
// Expect:
// #e@?q&zy+
// zyxwv
$param = array($ncharMatch, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING("UTF-8"), SQLSRV_SQLTYPE_NCHAR(iconv_strlen($ncharMatch)));
$testNCharMatch = "SELECT c_nchar FROM $myTable WHERE c_nchar LIKE ? COLLATE Latin1_General_BIN2";
$stmt = sqlsrv_prepare($conn, $testNCharMatch, array($param));
getResults($stmt);
// Expect:
// 㬚㔈♠既
// 㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
$param = array($charMatch, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_VARCHAR(strlen($charMatch)));
$testVarcharMatch = "SELECT c_varchar FROM $myTable WHERE c_varchar LIKE ? COLLATE Latin1_General_BIN2";
$stmt = sqlsrv_prepare($conn, $testVarcharMatch, array($param));
getResults($stmt);
// Expect:
// #e@?q&zy+
// zyxwv
$param = array($ncharMatch, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING("UTF-8"), SQLSRV_SQLTYPE_NVARCHAR(iconv_strlen($ncharMatch)));
$testNVarcharMatch = "SELECT c_nvarchar FROM $myTable WHERE c_nvarchar LIKE ? COLLATE Latin1_General_BIN2";
$stmt = sqlsrv_prepare($conn, $testNVarcharMatch, array($param));
getResults($stmt);
// Expect:
// 㬚㔈♠既
// 㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
function getResults($stmt)
{
sqlsrv_execute($stmt);
while ($res = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_NUMERIC)) {
print_r($res[0]);
echo "\n";
}
}
?>
PDO_SQLSRV
<?php
// Specify Azure Key Vault credentials using the KeyStoreAuthentication, KeyStorePrincipalId, and KeyStoreSecret keywords
// Otherwise, the local Windows Certificate Store will be used
$options = "sqlsrv:server=$myServer;database=$myDatabase;driver={ODBC Driver 18 for SQL Server};";
$options .= "ColumnEncryption=VBS-HGS,http://myattestationserver.mydomain/Attestation",
$conn = new PDO($options, $myUsername, $myPassword);
// Create the table and insert the test data
$stmt = $conn->query($createTable);
foreach ($testValues as $values) {
$stmt = $conn->prepare($insertData);
$stmt->execute($values);
}
// Encrypt the table in place
$stmt = $conn->query($encryptQuery);
// Test comparison and pattern matching on the encrypted table
echo "Test comparisons:\n";
$intThreshold = 0;
$testGreater = "SELECT c_integer FROM $myTable WHERE c_integer > ?";
$stmt = $conn->prepare($testGreater);
$stmt->bindParam(1, $intThreshold, PDO::PARAM_INT);
getResults($stmt);
// Expect:
// 1
// 100
$datetimeThreshold = "3000-01-01 00:00:00.0";
$testLess = "SELECT c_datetime2 FROM $myTable WHERE c_datetime2 < ?";
$stmt = $conn->prepare($testLess);
$stmt->bindParam(1, $datetimeThreshold, PDO::PARAM_STR);
getResults($stmt);
// Expect:
// 2019-12-31 01:00:00.0000000
// 1753-01-31 14:25:25.2500000
// 2112-03-15 23:40:10.1594000
$charThreshold = "abcd";
$ncharThreshold = "㬚㔈♠既";
$testGreaterEqual = "SELECT c_char FROM $myTable WHERE c_char >= ?";
$stmt = $conn->prepare($testGreaterEqual);
$stmt->bindParam(1, $charThreshold, PDO::PARAM_STR);
getResults($stmt);
// Expect:
// abcd
// zyxwv
$testLessEqual = "SELECT c_nchar FROM $myTable WHERE c_nchar <= ?";
$stmt = $conn->prepare($testLessEqual);
$stmt->bindParam(1, $ncharThreshold, PDO::PARAM_STR);
getResults($stmt);
// Expect:
// 㬚㔈♠既
// ઔܛ᎓Ե⅜
// 㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
$testNotGreater = "SELECT c_varchar FROM $myTable WHERE c_varchar !> ?";
$stmt = $conn->prepare($testNotGreater);
$stmt->bindParam(1, $charThreshold, PDO::PARAM_STR);
getResults($stmt);
// Expect:
// abcd
// #e@?q&zy+
// 7t
$testNotLess = "SELECT c_nvarchar FROM $myTable WHERE c_nvarchar !< ?";
$stmt = $conn->prepare($testNotLess);
$stmt->bindParam(1, $ncharThreshold, PDO::PARAM_STR);
getResults($stmt);
// Expect:
// 㬚㔈♠既
// 㶋㘚ᐋꗡ
echo "\nTest pattern matching:\n";
$charMatch = "%zy%";
$ncharMatch = "%㔈♠既%";
$testCharMatch = "SELECT c_char FROM $myTable WHERE c_char LIKE ? COLLATE Latin1_General_BIN2";
$stmt = $conn->prepare($testCharMatch);
$stmt->bindParam(1, $charMatch, PDO::PARAM_STR);
getResults($stmt);
// Expect:
// #e@?q&zy+
// zyxwv
$testNCharMatch = "SELECT c_nchar FROM $myTable WHERE c_nchar LIKE ? COLLATE Latin1_General_BIN2";
$stmt = $conn->prepare($testNCharMatch);
$stmt->bindParam(1, $ncharMatch, PDO::PARAM_STR,null,PDO::SQLSRV_ENCODING_UTF8);
getResults($stmt);
// Expect:
// 㬚㔈♠既
// 㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
$testVarcharMatch = "SELECT c_varchar FROM $myTable WHERE c_varchar LIKE ? COLLATE Latin1_General_BIN2";
$stmt = $conn->prepare($testVarcharMatch);
$stmt->bindParam(1, $charMatch, PDO::PARAM_STR);
getResults($stmt);
// Expect:
// #e@?q&zy+
// zyxwv
$testNVarcharMatch = "SELECT c_nvarchar FROM $myTable WHERE c_nvarchar LIKE ? COLLATE Latin1_General_BIN2";
$stmt = $conn->prepare($testNVarcharMatch);
$stmt->bindParam(1, $ncharMatch, PDO::PARAM_STR,null,PDO::SQLSRV_ENCODING_UTF8);
getResults($stmt);
// Expect:
// 㬚㔈♠既
// 㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
function getResults($stmt)
{
$stmt->execute();
while($res = $stmt->fetch(PDO::FETCH_NUM)) {
print_r($res[0]);
echo "\n";
}
}
?>
Výstup:
Test comparisons:
1
100
2019-12-31 01:00:00.0000000
1753-01-31 14:25:25.2500000
2112-03-15 23:40:10.1594000
abcd
zyxwv
㬚㔈♠既
ઔܛ᎓Ե⅜
㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
abcd
#e@?q&zy+
7t
㬚㔈♠既
㶋㘚ᐋꗡ
Test pattern matching:
#e@?q&zy+
zyxwv
㬚㔈♠既
㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
#e@?q&zy+
zyxwv
㬚㔈♠既
㛜ꆶ㕸㔈♠既ꁺꖁ㓫ޘ갧ᛄ
Viz také
Průvodce programováním pro ovladač PHP SQL
Referenční informace k rozhraní API ovladače SQLSRV
Referenční informace k rozhraní API ovladače PDO_SQLSRV
Použití funkce Always Encrypted s ovladači PHP pro SQL Server