我使用Always Encrypted来加密列中的值。我的连接字符串看起来像这样(一切正常,客户端能够解密值):
Driver={ODBC Driver 13 for SQL Server};Server=10.10.10.1\INST2;Database=test;Trusted_Connection=yes;ColumnEncryption=Enabled;
然后我尝试使用以下代码更新其中一个加密值:
ALTER PROCEDURE dbo.usp_SecurityUsers_GetDetails
(
@Firstname NVARCHAR(128)
)
AS
BEGIN;
UPDATE SecurityUsers
SET FirstName = @Firstname
WHERE login = 'system.export.service'
SELECT Login, FirstName, LastName
FROM SecurityUsers
END;
SP被称为这样:
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.NamedParameters = True
cmd.CommandText = "[dbo].[usp_SecurityUsers_GetDetails]"
cmd.Parameters.Append cmd.CreateParameter("@Firstname", adLongVarWChar, adParamInput, 128, "system_text")
cmd.CommandType = adCmdStoredProc
Set recordSet = cmd.Execute
但是我收到以下错误:
[Microsoft] [SQL Server的ODBC驱动程序13] [SQL Server]列/变量“@ P1”的加密方案不匹配。列/变量的加密方案是(encryption_type ='PLAINTEXT'),并且行'1'附近的表达式期望它是(encryption_type ='RANDOMIZED',encryption_algorithm_name ='AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name ='CEK_SecurityLevelNormal',column_encryption_key_database_name ='测试')(或更弱)。
这很奇怪,因为如果代码没有封装在存储过程中并且直接在SQL Server Management Studio中执行,我可以更新字段。
此外,直接在SSMS中调用SP
也可以。
编辑:
更新到.net 4.6.3
不会改变任何东西。我所看到的是,如果我将连接字符串ColumnEncryption=Enabled;
更改为Column Encryption Setting=Enabled;
,我会得到不同的错误:
[Microsoft] [SQL Server的ODBC驱动程序13] [SQL Server]操作数类型冲突:ntext与使用加密的nvarchar(128)不兼容(encryption_type ='RANDOMIZED',encryption_algorithm_name ='AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name ='CEK_SecurityLevelNormal',column_encryption_key_database_name = '测试')
我觉得问题必须是我试图修改数据的方式,因为我能够阅读它。它太蹩脚了。
在我的存储过程中,我有nvarchar(256)
。在ASP我使用adLongVarChar
而不是adVarWChar
。现在错误似乎更合理:
列/变量'@ P1'的加密方案不匹配。
结论是能够读取加密数据并使用ADO和ODBC驱动程序对其进行修改。