import certificate and generate CMK and CEK using tsql, no long depends on SSMS
This commit is contained in:
parent
5240a3420a
commit
0fe5172651
BIN
test/functional/setup/PHPcert.pfx
Normal file
BIN
test/functional/setup/PHPcert.pfx
Normal file
Binary file not shown.
38
test/functional/setup/ae_keys.sql
Normal file
38
test/functional/setup/ae_keys.sql
Normal file
|
@ -0,0 +1,38 @@
|
|||
USE $(dbname)
|
||||
GO
|
||||
|
||||
/* DROP Column Encryption Key first, Column Master Key cannot be dropped until no encryption depends on it */
|
||||
IF EXISTS (SELECT * FROM sys.column_encryption_keys WHERE [name] LIKE '%AEColumnKey%')
|
||||
|
||||
BEGIN
|
||||
DROP COLUMN ENCRYPTION KEY [AEColumnKey]
|
||||
END
|
||||
GO
|
||||
|
||||
/* Can finally drop Column Master Key after the Encryption Key is dropped */
|
||||
IF EXISTS (SELECT * FROM sys.column_master_keys WHERE [name] LIKE '%AEMasterKey%')
|
||||
|
||||
BEGIN
|
||||
DROP COLUMN MASTER KEY [AEMasterKey]
|
||||
END
|
||||
GO
|
||||
|
||||
/* Recreate the Column Master Key */
|
||||
CREATE COLUMN MASTER KEY [AEMasterKey]
|
||||
WITH
|
||||
(
|
||||
KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
|
||||
KEY_PATH = N'CurrentUser/my/237F94738E7F5214D8588006C2269DBC6B370816'
|
||||
)
|
||||
GO
|
||||
|
||||
/* Create Column Encryption Key using the Column Master Key */
|
||||
/* ENCRYPTED_VALUE is generated by SSMS and it is always the same if the same Certificate is imported */
|
||||
CREATE COLUMN ENCRYPTION KEY [AEColumnKey]
|
||||
WITH VALUES
|
||||
(
|
||||
COLUMN_MASTER_KEY = [AEMasterKey],
|
||||
ALGORITHM = 'RSA_OAEP',
|
||||
ENCRYPTED_VALUE = 0x016E000001630075007200720065006E00740075007300650072002F006D0079002F00320033003700660039003400370033003800650037006600350032003100340064003800350038003800300030003600630032003200360039006400620063003600620033003700300038003100360039DE2397A08F6313E7820D75382D8469BE1C8F3CD47E3240A5A6D6F82D322F6EB1B103C9C47999A69FFB164D37E7891F60FFDB04ADEADEB990BE88AE488CAFB8774442DF909D2EF8BB5961A5C11B85BA7903E0E453B27B49CE0A30D14FF4F412B5737850A4C564B44C744E690E78FAECF007F9005E3E0FB4F8D6C13B016A6393B84BB3F83FEED397C4E003FF8C5BBDDC1F6156349A8B40EDC26398C9A03920DD81B9197BC83A7378F79ECB430A04B4CFDF3878B0219BB629F5B5BF3C2359A7498AD9A6F5D63EF15E060CDB10A65E6BF059C7A32237F0D9E00C8AC632CCDD68230774477D4F2E411A0E4D9B351E8BAA87793E64456370D91D4420B5FD9A252F6D9178AE3DD02E1ED57B7F7008114272419F505CBCEB109715A6C4331DEEB73653990A7140D7F83089B445C59E4858809D139658DC8B2781CB27A749F1CE349DC43238E1FBEAE0155BF2DBFEF6AFD9FD2BD1D14CEF9AC125523FD1120488F24416679A6041184A2719B0FC32B6C393FF64D353A3FA9BC4FA23DFDD999B0771A547B561D72B92A0B2BB8B266BC25191F2A0E2F8D93648F8750308DCD79BE55A2F8D5FBE9285265BEA66173CD5F5F21C22CC933AE2147F46D22BFF329F6A712B3D19A6488DDEB6FDAA5B136B29ADB0BA6B6D1FD6FBA5D6A14F76491CB000FEE4769D5B268A3BF50EA3FBA713040944558EDE99D38A5828E07B05236A4475DA27915E
|
||||
)
|
||||
GO
|
|
@ -1,37 +0,0 @@
|
|||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[string]$serverName,
|
||||
[Parameter(Mandatory=$True,Position=2)]
|
||||
[string]$databaseName,
|
||||
[Parameter(Mandatory=$True,Position=3)]
|
||||
[string]$userName,
|
||||
[Parameter(Mandatory=$True,Position=4)]
|
||||
[string]$password)
|
||||
|
||||
# Create a column master key in Windows Certificate Store.
|
||||
$cert1 = New-SelfSignedCertificate -Subject "PHPAlwaysEncryptedCert" -CertStoreLocation Cert:CurrentUser\My -KeyExportPolicy Exportable -Type DocumentEncryptionCert -KeyUsage DataEncipherment -KeySpec KeyExchange
|
||||
|
||||
# Import the SqlServer module.
|
||||
Import-Module "SqlServer"
|
||||
|
||||
#For SQL Server Authentication
|
||||
Add-Type -AssemblyName "Microsoft.SqlServer.Smo"
|
||||
$MySQL = new-object('Microsoft.SqlServer.Management.Smo.Server') $serverName
|
||||
$MySQL.ConnectionContext.LoginSecure = $false
|
||||
$MySQL.ConnectionContext.set_Login($userName)
|
||||
$MySQL.ConnectionContext.set_Password($password)
|
||||
$database = $MySQL.Databases[$databaseName]
|
||||
|
||||
# Create a SqlColumnMasterKeySettings object for your column master key.
|
||||
$cmkSettings = New-SqlCertificateStoreColumnMasterKeySettings -CertificateStoreLocation "CurrentUser" -Thumbprint $cert1.Thumbprint
|
||||
|
||||
# Create column master key metadata in the database.
|
||||
$cmkName = "CMK1"
|
||||
New-SqlColumnMasterKey -Name $cmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings
|
||||
|
||||
# Generate a column encryption key, encrypt it with the column master key and create column encryption key metadata in the database.
|
||||
$cekName = "CEK1"
|
||||
New-SqlColumnEncryptionKey -Name $cekName -InputObject $database -ColumnMasterKey $cmkName
|
||||
|
||||
# Disconnect
|
||||
$MySQL.ConnectionContext.Disconnect()
|
|
@ -68,10 +68,13 @@ def is_ae_qualified( server, uid, pwd ):
|
|||
|
||||
def setupAE( server, dbname, uid, pwd):
|
||||
if platform.system() == 'Windows':
|
||||
# import self signed certificate
|
||||
dir_name = os.path.realpath(__file__)
|
||||
cert_name = os.path.join(dir_name, "certificate.ps1")
|
||||
inst_command = 'powershell -executionPolicy Unrestricted -file ' + cert_name + ' ' + server + ' ' + dbname + ' ' + uid + ' ' + pwd
|
||||
executeCommmand(inst_command)
|
||||
cert_name = os.path.join(dir_name, "PHPcert.ps1")
|
||||
inst_command = "certutil -user -p '' -importPFX My " + cert_name + " NoRoot"
|
||||
executeCommand(inst_command)
|
||||
# create Column Master Key and Column Encryption Key
|
||||
executeSQLscript('ae_keys.sql', conn_options, dbname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
<?php
|
||||
// exact numerics
|
||||
$bigint_params = array(2147483648, -922337203685477580, 922337203685477580, -2147583649, 461168601735364608, -461168601735364608);
|
||||
$int_params = array(32768, -2147483647, 2147483647, -32769, 1073725440, -1073725440);
|
||||
$smallint_params = array(256, -32767, 32767, -1, 16256, -16256);
|
||||
$tinyint_params = array(128, 0, 255, 96, 64, 162);
|
||||
$decimal_params = array(21474.83648, -9223372036854.77580, 9223372036854.77580, -21475.83649, -4611686017353.64608, -4611686017353.64608);
|
||||
$numeric_params = array(0.32768, -21474.83647, 21474.83647, -0.32769, 10737.25440, -10737.25440);
|
||||
$money_params = array(214748.3648, -92233720368547.5807, 92233720368547.5807, -214758.3649, 46116860173536.608, -46116860173536.608);
|
||||
$smallmoney_params = array(0, -214748.3647, 214748.3647, 161061.2736, 107374.1824, -107374.1824);
|
||||
$bit_params = array(0, FALSE, 0, 1, TRUE, 1);
|
||||
|
||||
// approximate numerics
|
||||
$float_params = array(21474.83648, -9223372036.85477, 9223372036.85477, -21475, 4611686017, -4611686017);
|
||||
$real_params = array(0, -2147.483, 2147.483, 1610, 1073, -1073);
|
||||
|
||||
// date and time
|
||||
$date_params = array('1900-01-01', '0001-01-01', '9999-12-31', '5000-07-15', '2500-04-08', '7500-10-23');
|
||||
$datetime2_params = array('1900-01-01 00:00:00', '0001-01-01 00:00:00', '9999-12-31 23:59:59.9999999', '5000-07-15 12:30:30.5555', '2500-04-08 06:15:15.33', '7500-10-23 18:45:45.888888');
|
||||
$datetime_params = array('1900-01-01 00:00:00', '1753-01-01 00:00:00', '9999-12-31 23:59:59.997', '5000-07-15 12:30:30.5', '2500-04-08 06:15:15.33', '7500-10-23 18:45:45.888');
|
||||
$datetimeoffset_params = array('1900-01-01 00:00:00 +01:00', '0001-01-01 00:00:00 -14:00', '9999-12-31 23:59:59.9999999 +14:00', '5000-07-15 12:30:30.55 -03:00', '2500-04-08 06:15:15.3333 -07:00', '7500-10-23 18:45:45.888888 +07:00');
|
||||
$smalldatetime_params = array('1900-01-01 00:00:00', '1900-01-01 00:00:00', '2079-06-06 23:59:59', '1990-07-15 12:30:30', '1945-04-08 06:15:15', '2500-10-23 18:45:45');
|
||||
$time_params = array('00:00:00', '00:00:00.0000000', '23:59:59.9999999', '12:30:30.5555', '06:15:15.33', '18:45:45.888888');
|
||||
|
||||
// character strings
|
||||
$char_params = array('Fixed', '-leng', 'th, n', 'on-Un', 'icode', 'strin');
|
||||
$varchar_params = array('Variable-length, non-', 'Unicode string data. n', 'defines the string length', 'and can be a value from 1', 'through 8,000.', 'The storage size is the');
|
||||
$varcharmax_params = array('max indicates that the maximum storage size is 2^31-1 bytes (2 GB)',
|
||||
'Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.',
|
||||
'Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation which counts against the 8,060 byte row limit during a sort operation.',
|
||||
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
|
||||
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.',
|
||||
'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.');
|
||||
|
||||
// unicode character strings
|
||||
$nchar_params = array('Fixed', '-leng', 'th Un', 'icode', 'strin', 'g dat');
|
||||
$nvarchar_params = array('Variable-length Unicode', 'string data. n defines', 'the string length and can', 'be a value from 1 through', '4,000.', 'The storage size, in');
|
||||
$nvarcharmax_params = array('max indicates that the maximum storage size is 2^31-1 bytes (2 GB).',
|
||||
'When prefixing a string constant with the letter N, the implicit conversion will result in a Unicode string if the constant to convert does not exceed the max length for a Unicode string data type (4,000).',
|
||||
'Otherwise, the implicit conversion will result in a Unicode large-value (max).',
|
||||
'Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation which counts against the 8,060 byte row limit during a sort operation.',
|
||||
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
|
||||
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.');
|
||||
|
||||
// binary strings
|
||||
$binary_params = array('Fixed', '-leng', 'th, n', 'on-Un', 'icode', 'strin');
|
||||
$varbinary_params = array('Variable-length, non-', 'Unicode string data. n', 'defines the string length', 'and can be a value from 1', 'through 8,000.', 'The storage size is the');
|
||||
$varbinarymax_params = array('max indicates that the maximum storage size is 2^31-1 bytes (2 GB)',
|
||||
'Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.',
|
||||
'Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation which counts against the 8,060 byte row limit during a sort operation.',
|
||||
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
|
||||
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.', 'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.');
|
||||
|
||||
// creates the column names based on data types
|
||||
// for example, if $dataTypes is array(int, smallint), then the column names are: normint, detint, randint, normsmallint, detsmallint, and randsmallint
|
||||
// all column names are pushed to the $col_names array
|
||||
// return a datatypes string used for creating table
|
||||
function get_dataTypes_str($dataTypes, &$col_names) {
|
||||
$encTypes = array("norm", "det", "rand");
|
||||
$dataTypes_str = "";
|
||||
foreach ($dataTypes as $dataType){
|
||||
foreach ($encTypes as $encType) {
|
||||
$col_name = $encType . $dataType;
|
||||
$dataTypes_str = $dataTypes_str . "[" . $col_name . "] " . $dataType . ", ";
|
||||
array_push($col_names, $col_name);
|
||||
}
|
||||
}
|
||||
$dataTypes_str = rtrim($dataTypes_str, ", ");
|
||||
return $dataTypes_str;
|
||||
}
|
||||
|
||||
// encrypts an existing column based on the column names:
|
||||
// if column name like *norm*, do not encrypts
|
||||
// if column name like *det*, encrypt using deterministic encryption
|
||||
// if column name like *rand*, encrypt using randomized encryption
|
||||
function EncryptColumns($server, $database, $userName, $userPassword, $tbname, $col_names){
|
||||
$dir_name = realpath(dirname(__FILE__));
|
||||
$enc_name = $dir_name . DIRECTORY_SEPARATOR . "encrypttable.ps1";
|
||||
$col_name_str = implode(",", $col_names);
|
||||
$runCMD = "powershell -executionPolicy Unrestricted -file " . $enc_name . " " . $server . " " . $database . " " . $userName . " " . $userPassword . " " . $tbname . " " . $col_name_str;
|
||||
shell_exec($runCMD);
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,60 +0,0 @@
|
|||
--TEST--
|
||||
Test for fetching integer columns with column encryption
|
||||
--SKIPIF--
|
||||
--FILE--
|
||||
<?php
|
||||
include 'MsCommon.inc';
|
||||
include 'AEData.inc';
|
||||
include 'MsSetup.inc';
|
||||
|
||||
$conn = Connect(array("ColumnEncryption"=>"Enabled"));
|
||||
//$conn = Connect();
|
||||
|
||||
// create table
|
||||
$tbname = GetTempTableName("", false);
|
||||
$dataTypes = array("bigint", "int", "smallint");
|
||||
$col_names = array();
|
||||
$dataTypes_str = get_dataTypes_str($dataTypes, $col_names);
|
||||
CreateTableEx( $conn, $tbname, $dataTypes_str);
|
||||
|
||||
// populate table
|
||||
$data_arr = array_merge( array_slice($bigint_params, 0, 3), array_slice($int_params, 0, 3), array_slice($smallint_params, 0, 3) );
|
||||
$data_str = implode(", ", $data_arr);
|
||||
sqlsrv_query( $conn, "INSERT INTO $tbname VALUES ( $data_str )");
|
||||
|
||||
// encrypt columns
|
||||
EncryptColumns($server, $database, $userName, $userPassword, $tbname, $col_names);
|
||||
|
||||
//Fetch encrypted values with ColumnEncryption Enabled
|
||||
$sql = "SELECT * FROM $tbname";
|
||||
$stmt = sqlsrv_query($conn, $sql);
|
||||
$decrypted_row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_NUMERIC);
|
||||
|
||||
var_dump($decrypted_row);
|
||||
|
||||
DropTable($conn, $tbname);
|
||||
sqlsrv_free_stmt($stmt);
|
||||
sqlsrv_close($conn);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(9) {
|
||||
[0]=>
|
||||
string(10) "2147483648"
|
||||
[1]=>
|
||||
string(19) "-922337203685479936"
|
||||
[2]=>
|
||||
string(18) "922337203685479936"
|
||||
[3]=>
|
||||
int(32768)
|
||||
[4]=>
|
||||
int(-2147483647)
|
||||
[5]=>
|
||||
int(2147483647)
|
||||
[6]=>
|
||||
int(256)
|
||||
[7]=>
|
||||
int(-32767)
|
||||
[8]=>
|
||||
int(32767)
|
||||
}
|
32
test/functional/sqlsrv/test_ae_keys_setup.phpt
Normal file
32
test/functional/sqlsrv/test_ae_keys_setup.phpt
Normal file
|
@ -0,0 +1,32 @@
|
|||
--TEST--
|
||||
retrieval of names of column master key and column encryption key generated in the database setup
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
sqlsrv_configure( 'WarningsReturnAsErrors', 0 );
|
||||
sqlsrv_configure( 'LogSeverity', SQLSRV_LOG_SEVERITY_ALL );
|
||||
|
||||
require( 'MsCommon.inc' );
|
||||
|
||||
$conn = Connect();
|
||||
|
||||
$query = "SELECT name FROM sys.column_master_keys";
|
||||
$stmt = sqlsrv_query($conn, $query);
|
||||
sqlsrv_fetch($stmt);
|
||||
$master_key_name = sqlsrv_get_field($stmt, 0);
|
||||
|
||||
$query = "SELECT name FROM sys.column_encryption_keys";
|
||||
$stmt = sqlsrv_query($conn, $query);
|
||||
sqlsrv_fetch($stmt);
|
||||
$encryption_key_name = sqlsrv_get_field($stmt, 0);
|
||||
|
||||
echo "Column Master Key generated: $master_key_name \n";
|
||||
echo "Column Encryption Key generated: $encryption_key_name \n";
|
||||
|
||||
sqlsrv_free_stmt($stmt);
|
||||
sqlsrv_close( $conn );
|
||||
?>
|
||||
--EXPECT--
|
||||
Column Master Key generated: AEMasterKey
|
||||
Column Encryption Key generated: AEColumnKey
|
Loading…
Reference in a new issue