是否可以通过明文类型确定ENCRYPTBYKEY最大返回值?

时间:2018-03-19 12:38:08

标签: sql-server tsql encryption sql-server-2016 sqldatatypes

我要加密现有表格中的几个字段。基本上,将使用以下加密技术:

private DataGrid CreateTextBoxesDataGrid(string name)
{
    DataGrid dataGrid = new DataGrid();
    dataGrid.Name = name;
    //row ???
    dataGrid.Style = Resources["AppSettingsDataGridStyle"] as Style;
    dataGrid.Columns.Add(CreateNameColumn());
    dataGrid.Columns.Add(CreateTextValueColumn());
    dataGrid.Columns.Add(CreateComentColumn());
    return dataGrid;
}

...
mainGrid.Children.Add(CreateTextBoxesDataGrid("eeej"));

ENCRYPTBYKEY返回CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'sm_long_password@' GO CREATE CERTIFICATE CERT_01 WITH SUBJECT = 'CERT_01' GO CREATE SYMMETRIC KEY SK_01 WITH ALGORITHM = AES_256 ENCRYPTION BY CERTIFICATE CERT_01 GO OPEN SYMMETRIC KEY SK_01 DECRYPTION BY CERTIFICATE CERT_01 SELECT ENCRYPTBYKEY(KEY_GUID('SK_01'), 'test') CLOSE SYMMETRIC KEY SK_01 DROP SYMMETRIC KEY SK_01 DROP CERTIFICATE CERT_01 DROP MASTER KEY ,最大大小为8,000字节。知道要加密的表字段(例如:varbinarynvarchar(128)varchar(31))如何定义新的bigint类型长度?

2 个答案:

答案 0 :(得分:2)

您可以看到完整的规范here

所以我们算一下:

  • 16字节键UID
  • _4 bytes headers
  • 16字节IV(对于AES,16字节分组密码)

再加上加密消息的大小:

  • _4字节幻数
  • _2字节完整性字节长度
  • _0字节完整性字节(警告:可能错误地放在表中)
  • _2字节(明文)消息长度
  • _m字节(明文)消息
  • CBC填充字节

CBC填充字节应按以下方式计算:

16 - ((m + 4 + 2 + 2) % 16)

始终应用填充。这将导致许多填充字节在1..16的范围内。一个偷偷摸摸的快捷方式是只添加16个字节,但这可能意味着您要指定最多15个从未使用过的字节。

我们可以将其缩短为36 + 8 + m + 16 - ((m + 8) % 16)60 + m - ((m + 8) % 16。或者,如果您使用上面指定的小技巧,并且您不关心浪费的字节:76 + m其中m是消息输入。

注意:

  • 请注意标头中的第一个字节包含方案的版本号;如果使用不同的内部消息格式或加密方案,此答案无法指定将添加或删除多少字节;
  • 强烈建议使用完整性字节,以防您想要保护您的数据库字段免受更改(保持帐户中的金额保密不如确保金额无法更改)。
  • 页面上的示例假定文本字符采用单字节编码。

答案 1 :(得分:1)

基于SQL Server 2008中的一些测试,以下公式似乎有效。请注意,@ ClearText是VARCHAR():

52 + (16 * ( ((LEN(@ClearText) + 8)/ 16) ) )

这与Maarten Bodewes的答案大致相符,除了我的测试显示DATALENGTH(myBinary)始终采用52 + (z * 16)的形式,其中z是整数。

LEN(myVarCharString)   DATALENGTH(encryptedString)
--------------------   -----------------------------------------
 0 through  7          usually 52, but occasionally 68 or 84 
 8 through 23          usually 68, but occasionally 84
24 through 39          usually 84
40 through 50          100

“ myVarCharString”是一个表列,定义为VARCHAR(50)。该表包含150,000条记录。提到“偶尔”的情况是,每10,000条记录中大约有1条会碰到更高的存储桶;很奇怪。对于LEN()为24或更高的值,没有足够的记录来得到怪异的异常。

这是一些Perl代码,其从终端输入的建议长度为“ myVarCharString”,并为EncryptByKey()结果产生预期的大小。函数“ int()”等效于“ Math.floor()”。

while($len = <>) { 
  print 52 + ( 16 * int( ($len+8) / 16 ) ),"\n";
}

您可能希望使用此公式来计算大小,然后添加16以允许出现异常。