使用始终加密的 Azure 密钥保管库从客户端应用程序通过存储过程插入 table

Insert into table via stored procedure from client application using always encrypted AzureKey vault

我创建了一个客户端应用程序,它使用 Always Encryption 执行所有加密和解密值。

我使用 Azure Key vault 来存储我的密钥。我关注了 this。使用硬编码查询 (INSERT INTO ....)

对我来说效果很好

但是当我尝试使用存储过程时,它不起作用。我已经提到过这个 Stack Post。但不幸的是 solutions/answer 并没有解决我的问题。所以我决定提出一个新问题。

这是我的 C# 代码

SqlCommand cmd = _sqlconn.CreateCommand();

// Use parameterized SQL to insert the data
cmd.CommandText = @"INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (@SSN, @FirstName, @LastName, @BirthDate);";

SqlParameter paramSSN = cmd.CreateParameter();
paramSSN.ParameterName = @"@SSN";
paramSSN.SqlDbType = SqlDbType.Char;
paramSSN.DbType = DbType.AnsiStringFixedLength;
paramSSN.Direction = ParameterDirection.Input;
paramSSN.Value = ssn;
paramSSN.Size = 11;
cmd.Parameters.Add(paramSSN);

SqlParameter paramFirstName = cmd.CreateParameter();
paramFirstName.ParameterName = @"@FirstName";
paramFirstName.DbType = DbType.String;
paramFirstName.Direction = ParameterDirection.Input;
paramFirstName.Value = firstName;
paramFirstName.Size = 50;
cmd.Parameters.Add(paramFirstName);

SqlParameter paramLastName = cmd.CreateParameter();
paramLastName.ParameterName = @"@LastName";
paramLastName.DbType = DbType.String;
paramLastName.Direction = ParameterDirection.Input;
paramLastName.Value = lastName;
paramLastName.Size = 50;
cmd.Parameters.Add(paramLastName);

SqlParameter paramBirthdate = cmd.CreateParameter();
paramBirthdate.ParameterName = @"@BirthDate";
paramBirthdate.SqlDbType = SqlDbType.Date;
paramBirthdate.Direction = ParameterDirection.Input;
paramBirthdate.Value = birthdate;
cmd.Parameters.Add(paramBirthdate);

cmd.ExecuteNonQuery();

当我为了使用存储过程而改变了一点。它会抛出类似

的错误

Additional information: Operand type clash: char is incompatible with varchar(20) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'TestDB') collation_name = 'SQL_Latin1_General_CP1_CI_AS'

string execute = @"[dbo].[insertsp]";

SqlCommand cmd = new SqlCommand(execute, _sqlconn);
cmd.CommandType = CommandType.StoredProcedure;

    SqlParameter paramSSN = cmd.CreateParameter();
    paramSSN.ParameterName = @"@SSN";
    paramSSN.SqlDbType = SqlDbType.Char;
    paramSSN.DbType = DbType.AnsiStringFixedLength;
    paramSSN.Direction = ParameterDirection.Input;
    paramSSN.Value = ssn;
    paramSSN.Size = 11;
    cmd.Parameters.Add(paramSSN);

    SqlParameter paramFirstName = cmd.CreateParameter();
    paramFirstName.ParameterName = @"@FirstName";
    paramFirstName.DbType = DbType.String;
    paramFirstName.Direction = ParameterDirection.Input;
    paramFirstName.Value = firstName;
    paramFirstName.Size = 50;
    cmd.Parameters.Add(paramFirstName);

    SqlParameter paramLastName = cmd.CreateParameter();
    paramLastName.ParameterName = @"@LastName";
    paramLastName.DbType = DbType.String;
    paramLastName.Direction = ParameterDirection.Input;
    paramLastName.Value = lastName;
    paramLastName.Size = 50;
    cmd.Parameters.Add(paramLastName);

    SqlParameter paramBirthdate = cmd.CreateParameter();
    paramBirthdate.ParameterName = @"@BirthDate";
    paramBirthdate.SqlDbType = SqlDbType.Date;
    paramBirthdate.Direction = ParameterDirection.Input;
    paramBirthdate.Value = birthdate;
    cmd.Parameters.Add(paramBirthdate);

    cmd.ExecuteNonQuery();

这是启用加密后的架构

CREATE TABLE [dbo].[patients]
(
    [ssn] [varchar](20) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL,
    [FirstName] [varchar](50) NULL,
    [LastName] [varchar](50) NULL,
    [BirthDate] [datetime] NULL
)

(PS: 我已经在我的连接字符串中启用了 Column Encryption Setting=enabled。还尝试了 EXEC sys.sp_refresh_parameter_encryption @name = '[dbo].[sp]' - 两者都不起作用我)

只是区分大小写的问题(@ssn 和@SSN)。

请不要忘记

SQL 不敏感

C# 区分大小写