SQL Server 2016如何从命令行读取/写入始终加密的列?

问题描述:

我能够读取和写入从C#ASP.NET应用程序始终加密的列。不过,我需要从sqlcmd来完成。SQL Server 2016如何从命令行读取/写入始终加密的列?

经过一番研究,我发现here,你需要-g参数来激活列加密设置,并更新到sqlcmd版本13.1,我已经使用“sqlcmd - ?”进行了验证。

所以,我做了一个测试表:

create table tmp 
(
tmp_id int identity(1,1) not null, 
test varchar(500) 
COLLATE Latin1_General_BIN2 
ENCRYPTED WITH 
    (ENCRYPTION_TYPE = RANDOMIZED, 
    ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', 
    COLUMN_ENCRYPTION_KEY = MY_Encryption_Key) 
null 
); 

并取得了TEST.SQL如下:

insert into tmp (test) values ('mytest'); 

我打电话SQLCMD是这样的:

sqlcmd.exe -g -b -S "localhost\SQL2016" -d "my_db_name" -i "D:\test.sql" -U "my_username" -P "my_password" 

但我得到以下错误,无论是否使用“-g”:

Operand type *: varchar is incompatible with varchar(8000) encrypted with (encryption_type = 'RANDOMIZED', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'MY_Encryption_Key', column_encryption_key_database_name = 'my_db_name') collation_name = 'SQL_Latin1_General_CP1_CI_AS' 

如果我改变TEST.SQL到:

declare @test varchar(8000) = 'mytest'; 
insert into tmp (test) values (@test); 

然后我得到另一个错误(还带或不带-g):

Encryption scheme mismatch for columns/variables '@test'. The encryption scheme for the columns/variables is (encryption_type = 'PLAINTEXT') and the expression near line '2' expects it to be (encryption_type = 'RANDOMIZED', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'MY_Encryption_Key', column_encryption_key_database_name = 'my_db_name') (or weaker). 

我需要这个,因为现在有一个C#接受平面文件的应用程序,然后通过调用“.sql”文件通过命令行将其加载到数据库中。现在一些列需要加密。所以,我们需要sqlcmd来读/写加密列以避免重写C#.NET中的所有逻辑。

我做错了什么?这甚至有可能吗?为什么sqlcmd的“-g”参数没有什么区别?

+0

尝试在插入时将值转换为varchar(8000)。 –

+0

它没有工作,我已经尝试 – user7792598

+0

如果这个工作,你会有效*规避总是加密功能,因为你的.sql文件中的字符串*未加密*。 '-g'选项允许'sqlcmd'从AE列中检索数据(如果它有权访问这些键),但它仍然不能使用未加密的值运行任意T-SQL,但不能超过其他客户端。这些值必须从支持它的客户端进行正确的参数化。这意味着纯文本T-SQL脚本已经不存在了。 SSMS现在有一些黑客支持,因为它*是一个痛苦的屁股,但'sqlcmd'不够复杂。 –

当前使用以下语法将数据插入到始终加密的列中是仅在SSMS中受支持。

declare @test varchar(8000) = 'mytest'; 
insert into tmp (test) values (@test); 

你可以找到关于这个herehere

创建细节表TMP tmp_id INT标识(1,1)NOT NULL,

测试为nvarchar(11)

COLLATE Latin1_General_BIN2 ENCRYPTED WITH (将encryption_type =随机, 算法= 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = CEK_Auto1)
);

创建步骤[dbo]。[Proc_Test] @test为nvarchar(11) AS

插入到TMP(测试)值(@test);

上面的代码在SSMS中为我工作。