我使用SSMS中的加密列功能加密现有表中的多个列。我选择生成Powershell脚本而不是加密向导中的列,以便我可以在以后加密列。脚本如下:
# Generated by SQL Server Management Studio at 3:03 PM on 4/05/2018
Import-Module SqlServer
# Set up connection and database SMO objects
$sqlConnectionString = "Data Source=.;Initial Catalog=MyDatabase;Integrated Security=True;MultipleActiveResultSets=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;Packet Size=4096;Application Name=`"Microsoft SQL Server Management Studio`""
$smoDatabase = Get-SqlDatabase -ConnectionString $sqlConnectionString
# If your encryption changes involve keys in Azure Key Vault, uncomment one of the lines below in order to authenticate:
# * Prompt for a username and password:
#Add-SqlAzureAuthenticationContext -Interactive
# * Enter a Client ID, Secret, and Tenant ID:
#Add-SqlAzureAuthenticationContext -ClientID '<Client ID>' -Secret '<Secret>' -Tenant '<Tenant ID>'
# Change encryption schema
$encryptionChanges = @()
# Add changes for table [dbo].[Voucher]
$encryptionChanges += New-SqlColumnEncryptionSettings -ColumnName dbo.Voucher.Code -EncryptionType Randomized -EncryptionKey "cek"
Set-SqlColumnEncryption -ColumnEncryptionSettings $encryptionChanges -InputObject $smoDatabase
但是,当我运行脚本时,我从Set-SqlColumnEncryption
cmdlet获得以下异常:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an
invocation. ---> System.TypeInitializationException: The type initializer for
'Microsoft.SqlServer.Management.AlwaysEncrypted.Management.AlwaysEncryptedManagement' threw an
exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json,
Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The
system cannot find the file specified.
我也更新了Sqlserver模块。当然,我不必手动将Newtonsoft.Json.dll文件放入SqlServer模块目录。有什么想法吗?
答案 0 :(得分:0)
您正在使用&#39;始终加密&#39;。我假设您的列主密钥存储在运行脚本的计算机上的Windows证书存储中。并且,我假设您的密钥设置正确。
我们说我有一个有架构的表:
CREATE TABLE dbo.property_bag (
id int identity(1,1) primary key
, insert_user sysname not null
, insert_date datetime2 not null
, insert_source sysname not null
, [stuff] varchar(max) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED
, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
, COLUMN_ENCRYPTION_KEY = [dbo-property_bag]) NULL
);
GO
这是一个将数据插入我的表格的脚本:
$insert_count = 10
$words = @('bobby','mikey','billy','suzie','kenny','narav','navneet','rachel','jose','juan')
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = “Server='<db-server>';Database='<db>';Column Encryption Setting=enabled;Integrated Security=True;”
$hostname = $env:computername
try {
$conn.Open()
for ($i = 1; $i -le $insert_count; $i++) {
$val = Get-Random -Maximum 10
$word_to_insert = $words[$val]
$sqlcmd = New-Object System.Data.SqlClient.SqlCommand
$sqlcmd.Connection = $conn
$sqlcmd.CommandText = “INSERT INTO dbo.property_bag ([insert_user], [insert_date], [insert_source], [stuff]) VALUES (SUSER_SNAME(), GETDATE(), '${hostname}', @value)”
$sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@value",[Data.SQLDBType]::VarChar, 4000))) | Out-Null
$sqlcmd.Parameters[0].Value = $word_to_insert
$sqlcmd.ExecuteNonQuery() | Out-Null
Write-Progress -Activity "Inserting Records..." -Status "Progress $($i / $insert_count * 100)%" -percentComplete ($i / $insert_count)
}
} finally {
$conn.Close()
$conn.Dispose()
}
当我使用数据库注册列主密钥(通过对象资源管理器)时,我将路径设置为&#34; CurrentUser / My /&#34;。 SQL Server会将该位置传递回驱动程序,驱动程序将在本地密钥存储区中搜索与提供的指纹匹配的证书。该密钥(在我的情况下是在运行脚本的app-server上)将解密列加密密钥。这些都不在脚本中详细说明。它是数据库中的所有设置。以下是此示例的数据流:
在您的示例中,连接字符串不包含&#34;列加密设置=启用&#34;。我不相信Get-SqlDatabase
命令行开关采用连接字符串参数。我相信你将它传递给一个实例对象。只有很多东西看起来不安静。
如果您的密钥设置不正确,我可以here启动。
答案 1 :(得分:0)
我遇到了完全相同的问题,我相信这是特定操作系统和Sql Server混合的某种组件集成问题。
例如,我尝试在笔记本电脑上运行powershell脚本时收到此错误。我的笔记本电脑恰好使用Windows 10和Sql Server Management Studio 17.2(这是最终生成ps1的东西)。此外,我的笔记本电脑确实包含正确目录中的Newtonsoft.Json.dll。
然而,我跳到服务器,该服务器使用的是Windows 2012 R2和SSMS 17.2,并且脚本可以正常工作!
最终,就好像在Windows10 / SSMS17.2安装中缺少某种程序集绑定重定向,Windows2012R2 / SSMS17.2似乎正确解析了。