我正在寻找一个简单的(理想的内联)tsql语句来实现以下翻译。我们希望隐藏的数据中包含参考编号字段。它的格式为AAA1234,总是7位数,前三个是字母字符,其余是数字。我们可以使用某种强加密,但我们也希望数据用户能够在需要时解密客户编号,以便他们可以交叉引用。交叉引用很可能是从纸质报告中完成的。
对于基本的模糊,有很多方法,例如我们可以转换
编辑 - 假设要求如上所述,我知道我的方式有关加密,安全性,用户身份验证/授权,并且有充分理由希望以这种方式解决问题。没有蛇油,没有大坏程序员猜测要求。有没有人有一些整洁的SQL来做到这一点?
答案 0 :(得分:3)
其他人已经提到整个概念都是有问题的 你应该问问自己这种加密是什么类型的攻击(我更喜欢这里的'加扰'这个词来区分'真正的'加密)可以防止,它无法阻止什么样的攻击,以及它们如何对应你实际的攻击期待并试图阻止。
一般来说,你所描述的想法最多是“通过默默无闻的安全”,因此它增加了一些“安全感”,但几乎没有“真正的安全性”。
然而,这里有一些简单的解决方案。
<强> 1。
将字符串存储为十六进制表示
'ABC1234'变为'0x41424331323334'。
DECLARE @x varchar(30)
-- scrambling: convert string to its hex representation
SET @x = sys.fn_varbintohexstr(CAST('ABC1234' AS varbinary))
SELECT @x -- returns '0x41424331323334'
-- unscrambling
EXEC('SELECT CAST(' + @x + ' AS varchar(30))')
这里我使用了未记录的fn_varbintohexstr函数来加扰和EXEC来解密。你不能轻易地用这种方式解读所有数据,并且必须通过一条记录来做 - 你可以看到它是坏的(不方便)或好的(攻击者必须一点思考才能一次获得所有未加扰的数据)。
如果您不喜欢这些转换,还有other techniques二进制到字符串转换。
<强> 2。
将字符串存储为数字(使用随机盐进行异或)
'ABC1234'变为-5389962212370045368。
请注意,这对于长度超过8个字符的字符串不起作用,因为MSSQL内置XOR仅适用于整数(其中最大的长度为8个字节)。当然,可以创建一个UDF来对任意长二进制类型执行XOR,但在这里我试着保持简单。
-- use a random salt (a kind of 'shared secret')
DECLARE @salt bigint
SET @salt = 0xf47142dde0d49248
DECLARE @x bigint
-- scramble: cast to bigint and XOR with the seed
SET @x = CAST(CAST('ABC1234' AS binary(8)) AS BIGINT) ^ @salt
SELECT @x -- returns -5389962212370045368
-- unscramble
SELECT CAST(CAST(@x ^ @salt as varbinary) as varchar)
这里,随机盐用于加扰和解扰。您可以尝试在其上构建一些额外的安全性 - 比如,将salt值存储在应用程序中并在每次调用时将其传递给数据库,这样单独的数据库访问不足以轻松获取数据(当然,这是仍然很容易打破 - 例如,有一个已知的明文攻击)。
第3。使用内置对称加密
'ABC1234'变为0x01000000AECBC6E2A5B51F09B6953DFD7A648675E4DD3CE46E93BC0D。
这依赖于MSSQL2005 +内置对称加密功能(我相信,在内部它使用AES256或3DES,具体取决于平台)。
-- use random passphrase
DECLARE @pwd varchar(30)
SET @pwd = 0xA0880D9980AE0C4EA28A8A247763AB5B
SELECT @pwd
-- encrypt with the passphrase
DECLARE @x varbinary(8000)
SET @x = EncryptByPassPhrase(@pwd, 'ABC1234')
SELECT @x -- 0x01000000AECBC6E2A5B51F09B6953DFD7A648675E4DD3CE46E93BC0D
-- decrypt
SELECT CAST(DecryptByPassPhrase(@pwd, @x) AS varchar)
另请参阅EncryptByKey and other crpytographic functions和How to: Encrypt a Column of Data。这里使用了一些真正的加密,并且MSSQL本身支持密钥管理,因此这可能是构建一些“真实”安全性的基础(当然,还有很多方法可以解决这个问题:-))。
答案 1 :(得分:1)
更好的做法是在列中使用哈希,然后创建另一个存储哈希值和引用号的表,然后限制对该表的访问。
答案 2 :(得分:0)
数据的用户需要访问它,但字段应该被遮挡,所以没有人可以读取它?然后,你想做什么,告诉需要访问有关你的snakeoil算法的数字的人,然后希望他们不会告诉别人?这种方式会使您的用户更加复杂,对您的雇主也不安全。这在我眼里是不可接受的。你需要某种用户限制或强加密,但加密不是这里的首选,因为每个人都需要相同的密钥,所以不需要很长时间,直到有人未经授权才能获得密钥,然后你必须改变整个数据库。实际上,最佳方式是良好的用户身份验证和限制系统。