代码之家  ›  专栏  ›  技术社区  ›  MrTelly

SQL字符串转换

  •  0
  • MrTelly  · 技术社区  · 14 年前

    我正在寻找一个简单的(理想的内联)tsql语句来实现以下翻译。我们希望在数据中隐藏参考号字段。它的格式是aaa1234,总是7位,前三位是字母字符,其余是数字。我们可以使用某种强加密,但我们也希望数据的用户能够在需要时破译客户号码,以便他们可以交叉引用。很可能交叉引用将从一份书面报告中完成。

    对于基本的遮蔽有很多方法,例如我们可以转换

    • ABC1234至ZYX4321(即A变为Z、B-Y等)
    • ABC1234至0102034321(即A变为01,Z变为26)
    • ABC1234到CBA3412(颠倒字母,用3和4交换数字1和2)

    编辑-假设需求如前所述,我知道如何绕过加密、安全性、用户身份验证/授权,并且有真正的理由希望以这种方式解决问题。没有蛇油,没有大坏程序员猜出的要求。有没有人可以用一些简洁的sql来完成这个任务?

    3 回复  |  直到 14 年前
        1
  •  3
  •   VladV    14 年前

    其他人已经提到,整个概念,嗯,值得怀疑。
    你应该扪心自问,这种加密(我更喜欢这里的“加扰”这个词,以区别于“真正的”加密)可以防止什么样的攻击,它不能防止什么样的攻击,以及它们如何对应于你实际期望和试图防止的攻击。

    一般来说,正如你所描述的,这种想法充其量是“通过模糊来实现安全”,所以它增加了一些“安全感”,但几乎没有“真正的安全感”。

    不过,这里有一些简单的解决办法。

    一。 将字符串存储为十六进制表示形式
    “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. 将字符串存储为数字(用随机盐进行xored)
    “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值存储在应用程序中,并在每次调用时将其传递给数据库,因此仅数据库访问不足以轻松获取数据(当然,这仍然很容易中断—例如,使用已知的明文攻击)。

    三。使用内置对称加密
    “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本身就支持密钥管理,因此这可能是构建一些“真正”安全性的基础(当然,还有很多方法可以搞糟它:-)。

        2
  •  1
  •   Ignacio Vazquez-Abrams    14 年前

    更好的做法是在列中使用散列,然后创建另一个存储散列和引用号的表,然后限制对该表的访问。

        3
  •  0
  •   joni    14 年前

    数据的用户需要访问它,但是字段应该被隐藏,这样就没有人可以读取它了?然后,你想怎么做,告诉那些需要访问你的蛇毒算法的人,然后希望他们不会告诉别人?这种方式会让你的用户更加复杂,也会让你的雇主更加不安全。在我看来这是不可接受的。您需要某种用户限制或强加密,但加密不是这里的首选,因为每个人都需要相同的密钥,因此不需要很长时间,直到未经授权的人获得密钥,然后您必须更改整个数据库。最好的方法,真的,是一个好的用户认证和限制系统。