簡體   English   中英

varchar與使用(encryption_type ='DETERMINISTIC'加密的varchar(50)不兼容

[英]varchar is incompatible with varchar(50) encrypted with (encryption_type = 'DETERMINISTIC'

我試圖從我的應用程序傳遞一個參數,以在存儲過程中進行搜索。 我像這樣傳遞參數:

SqlParameter param1 = new SqlParameter(@"@FilterCustomerPO", "G06756");
param1.DbType = DbType.AnsiString;
param1.Direction = ParameterDirection.Input;
param1.Size = 50;

sqlCmd.Parameters.Add(param1);

在存儲過程中,它的定義如下:

ALTER PROCEDURE [dbo].[usp_POListing]
    @FilterCustomerPO VARCHAR (50)
AS
BEGIN
    SELECT * 
    FROM [Order]
    WHERE PONumber = @FilterCustomerPO
END

PONumber列使用DETERMINISTIC加密類型加密。

傳遞值時,出現錯誤:

操作數類型沖突:varchar與varchar(50)不兼容,加密方式為(encryption_type ='DETERMINISTIC',encryption_algorithm_name ='AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name ='ColumnEncryptionKey',column_encryption_key_Port_atin__1 ____ Data_atin___1

我見過很多其他人對此進行報告,但是這些解決方案都不適合我。 如您所見,我正在使用參數化查詢,所以不確定我可能會丟失什么。

編輯:

我也嘗試過以這種方式傳遞參數-同樣的錯誤:

sqlCmd.Parameters.Add("FilterCustomerPO", SqlDbType.VarChar, 50);
sqlCmd.Parameters["FilterCustomerPO"].Value = "G06756"

訂單表的定義如下:

CREATE TABLE [dbo].[Order]
(
    [OrderID] [INT] IDENTITY(1,1) NOT NULL,
    [CustomerID] [INT] NOT NULL,
    [OrderNumber] [INT] NOT NULL,
    [DBCOrderNumber] [VARCHAR](25) NOT NULL,
    [PONumber] [VARCHAR](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [ColumnEncryptionKey], ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
    [BillingName] [VARCHAR](255) NOT NULL,

    CONSTRAINT [PK_Order] 
        PRIMARY KEY CLUSTERED ([OrderID] ASC)
                    WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

我的客戶端連接字符串還包括“ Column Encryption Setting=Enabled

請注意:我可以檢索數據。 這是我將參數發送到查詢中,並在收到錯誤時嘗試進行比較/過濾的時間。

這是AlwaysEncrypted ,僅使用客戶端加密密鑰。 它旨在防止SQL Server(或其管理員)解密數據。 如果您希望使用服務器管理的密鑰進行列加密,SQL Server也可以這樣做,但這是另一項功能。 請參閱加密數據列

在AlwaysEncrypted數據中,Order.PONumber的類型實際上不僅僅是varchar(50) 它的

[varchar](50) COLLATE Latin1_General_BIN2 
    ENCRYPTED WITH (
      COLUMN_ENCRYPTION_KEY = [ColumnEncryptionKey], 
      ENCRYPTION_TYPE = Deterministic, 
      ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256')

這就是列類型的全部內容 ,因此您不能使用varchar(50)類型的參數。 為了在此列上進行搜索,客戶端必須使用指定的密鑰和算法對參數值進行加密,因此SQL Server可以將確定性加密的列值與加密的參數值進行匹配。 SQL Server沒有列加密密鑰,因此它無法解密列值或加密參數值。

SQL Server具有將加密的表參數傳播到存儲過程或函數的能力。 這似乎工作正常。 要檢查存儲過程參數是否已選擇列加密,請檢查sys.parameters。 例如

select name, encryption_type_desc, encryption_algorithm_name
from sys.parameters
where object_id = object_id('usp_POListing')

我創建了一個簡單的repro,並且能夠像這樣調用存儲過程:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp27
{
    class Program
    {
        static void Main(string[] args)
        {

            using (var con = new SqlConnection("server=localhost;database=testdb;integrated security=true;Column Encryption Setting=enabled"))
            {
                con.Open();

                var sqlCmd = new SqlCommand("usp_POListing", con);
                sqlCmd.CommandType = CommandType.StoredProcedure;

                var param1 = new SqlParameter("@FilterCustomerPO", "G06756");
                param1.SqlDbType = SqlDbType.VarChar;
                param1.Size = 50;
                param1.Direction = ParameterDirection.Input;

                sqlCmd.Parameters.Add(param1);

                var dt = new DataTable();
                using (var rdr = sqlCmd.ExecuteReader())
                {
                    dt.Load(rdr);
                }
            }
        }
    }
}

一般請參閱使用始終加密的.NET Framework數據提供程序進行開發

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM