【问题标题】:SQL Server 2016 How to read/write to an always encrypted column from command line?SQL Server 2016 如何从命令行读取/写入始终加密的列?
【发布时间】: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


【解决方案1】:

目前仅在 SSMS 中支持

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

您可以找到有关此herehere 的详细信息

【讨论】:

    【解决方案2】:

    创建表 tmp ( tmp_id int identity(1,1) not null,

    测试 nvarchar(11)

    COLLATE Latin1_General_BIN2 加密 (加密类型 = 随机, 算法 = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = CEK_Auto1)
    );

    创建过程 [dbo].[Proc_Test] @test nvarchar(11) 作为

    插入 tmp(测试)值(@test);

    以上代码在 SSMS 中适用于我。

    【讨论】:

    • 您的代码创建了一个表并创建了一个存储过程,但没有调用该存储过程。最后使用它,我得到Operand type clash: varchar is incompatible with nvarchar(11) encrypted with (encryption_type = 'RANDOMIZED', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'tkcMuckAround')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多