【发布时间】:2017-05-24 15:34:18
【问题描述】:
我能够从 C# ASP.NET 应用程序读取和写入始终加密的列。但是,我需要从 sqlcmd 执行。
经过一番研究,我发现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 clash: 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”参数不起作用?
【问题讨论】:
-
在插入时尝试将值转换为 varchar(8000)。
-
没用,我已经试过了
-
如果这行得通,您将有效地规避始终加密功能,因为您的 .sql 文件中的字符串未加密。
-g选项允许sqlcmd从 AE 列中检索数据(如果它可以访问密钥),但它仍然不能使用未加密的值运行任意 T-SQL,与其他客户端一样。这些值必须从支持它的客户端正确参数化。这意味着纯文本 T-SQL 脚本已经过时了。 SSMS 现在对此提供了一些 hacky 支持,因为它很麻烦,但sqlcmd还不够成熟。
标签: c# command-line sql-server-2016 always-encrypted