【问题标题】:How to decrypt a password from SQL server?如何从 SQL Server 解密密码?
【发布时间】:2010-09-15 10:59:46
【问题描述】:

我在 sql server 2000 中有这个查询:

select pwdencrypt('AAAA')

输出一个加密的'AAAA'字符串:

0x0100CF465B7B12625EF019E157120D58DD46569AC7BF4118455D12625EF019E157120D58DD46569AC7BF4118455D

如何转换(解密)来自其来源(即“AAAA”)的输出?

【问题讨论】:

  • 我谷歌“如何在 SQL 中加密密码”并找到这篇文章!!!!!

标签: sql-server encryption hash passwords


【解决方案1】:

我相信 pwdencrypt 使用的是散列,因此您无法真正反转散列字符串 - 该算法的设计是不可能的。

如果您要验证用户输入的密码,通常的技术是对其进行哈希处理,然后将其与数据库中的哈希版本进行比较。

这就是您可以验证用户输入的表格的方式

SELECT password_field FROM mytable WHERE password_field=pwdencrypt(userEnteredValue)

用用户输入的值替换 userEnteredValue :)

【讨论】:

  • pwdencrypt() 在每次调用后返回不同的结果 - 您无法通过比较使用 pwdencrypt 生成的两个哈希来比较密码。相反,您必须使用 pwdcompare('plaintext psw', 'hashed psw') 正确比较它们。
  • 请注意,哈希是不可逆的,因为两个不同的字符串可能等于相同的哈希。这样就不可能知道它最初是什么。遇到两个等于相同哈希的字符串的可能性极低,但它通过无法解密它使哈希更加安全。
  • 更准确地说,您无法解密散列,因为散列不包含加密数据。散列!=加密。散列是有损操作,加密不是。
  • 更重要的是,您不能反转散列,因为散列是有损操作。根据设计,缺少信息,因此散列值无法用于重新创建原始信息,可用信息不足。假设一个人知道哈希算法和盐,“逆转”的唯一希望是生成一个彩虹表来查找哈希的原始值。 -
【解决方案2】:

您无法再次解密此密码,但还有另一种名为“pwdcompare”的方法。这是一个如何使用 SQL 语法的示例:

USE TEMPDB
GO
declare @hash varbinary (255)
CREATE TABLE tempdb..h (id_num int, hash varbinary (255))
SET @hash = pwdencrypt('123') -- encryption
INSERT INTO tempdb..h (id_num,hash) VALUES (1,@hash)
SET @hash = pwdencrypt('123')
INSERT INTO tempdb..h (id_num,hash) VALUES (2,@hash)
SELECT TOP 1 @hash = hash FROM tempdb..h WHERE id_num = 2
SELECT pwdcompare ('123', @hash) AS [Success of check] -- Comparison
SELECT * FROM tempdb..h
INSERT INTO tempdb..h (id_num,hash) 
VALUES (3,CONVERT(varbinary (255),
0x01002D60BA07FE612C8DE537DF3BFCFA49CD9968324481C1A8A8FE612C8DE537DF3BFCFA49CD9968324481C1A8A8))
SELECT TOP 1 @hash = hash FROM tempdb..h WHERE id_num = 3
SELECT pwdcompare ('123', @hash) AS [Success of check] -- Comparison
SELECT * FROM tempdb..h
DROP TABLE tempdb..h
GO

【讨论】:

    【解决方案3】:

    你意识到你可能正在为自己的未来做一根棍子。 pwdencrypt() 和 pwdcompare() 是未记录的函数,在 SQL Server 的未来版本中可能表现不同。

    为什么不在访问数据库之前使用可预测的算法(例如 SHA-2 或更好的算法)对密码进行哈希处理?

    【讨论】:

    • HASHBYTES('sha1', 'password')
    【解决方案4】:

    快速google 表示 pwdencrypt() 不是确定性的,并且您的语句 select pwdencrypt('AAAA') 在我的安装中返回不同的值!

    另见这篇文章http://www.theregister.co.uk/2002/07/08/cracking_ms_sql_server_passwords/

    【讨论】:

    • pwdencrypt() 方法为每次调用返回一个不同的哈希值——无论如何 pwdcompare() 方法可以比较两个哈希值。
    【解决方案5】:

    您真的不应该对密码进行解密。

    您应该对输入应用程序的密码进行加密,并与数据库中的加密密码进行比较。

    编辑 - 如果这是因为忘记了密码,则设置一个机制来创建新密码。

    【讨论】:

      【解决方案6】:

      SQL Server 密码哈希算法:

      hashBytes = 0x0100 | fourByteSalt | SHA1(utf16EncodedPassword+fourByteSalt)
      

      例如,散列密码“正确的马电池订书钉”。首先我们生成一些随机盐:

      fourByteSalt = 0x9A664D79;
      

      然后将密码(以 UTF-16 编码)与盐一起散列:

       SHA1("correct horse battery staple" + 0x9A66D79);
      =SHA1(0x63006F007200720065006300740020006200610074007400650072007900200068006F00720073006500200073007400610070006C006500 0x9A66D79)
      =0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
      

      syslogins 表中存储的值是以下内容的串联:

      [标题] + [盐] + [哈希]
      0x0100 9A664D79 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3

      您可以在 SQL Server 中看到的内容:

      SELECT 
         name, CAST(password AS varbinary(max)) AS PasswordHash
      FROM sys.syslogins
      WHERE name = 'sa'
      
      name  PasswordHash
      ====  ======================================================
      sa    0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
      
      • 版本头:0100
      • 盐(四个字节):9A664D79
      • 哈希:6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3(SHA-1 为 20 字节;160 位)

      验证

      您通过执行相同的哈希来验证密码:

      • 从保存的PasswordHash: 0x9A664D79 中获取盐

      并再次执行哈希:

      SHA1("correct horse battery staple" + 0x9A66D79);
      

      这将得到相同的哈希值,并且您知道密码是正确的。

      以前很好,现在很弱

      SQL Server 7 于 1999 年引入的散列算法适用于 1999 年。

      • 密码哈希加盐很好。
      • 最好将盐附加到密码,而不是附加它。

      但今天它已经过时了。它只运行一次哈希,它应该运行几千次,以阻止暴力攻击。

      事实上,作为检查的一部分,Microsoft 的 Baseline Security Analyzer 会尝试暴力破解密码。如果它猜到了,它会将密码报告为弱密码。它确实得到了一些。

      暴力破解

      为了帮助您测试一些密码:

      DECLARE @hash varbinary(max)
      SET @hash = 0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
      --Header: 0x0100
      --Salt:   0x9A664D79
      --Hash:   0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
      
      DECLARE @password nvarchar(max)
      SET @password = 'password'
      
      SELECT
          @password AS CandidatePassword,
          @hash AS PasswordHash,
          
          --Header
          0x0100
          +
          --Salt
          CONVERT(VARBINARY(4), SUBSTRING(CONVERT(NVARCHAR(MAX), @hash), 2, 2))
          +
          --SHA1 of Password + Salt
          HASHBYTES('SHA1', @password + SUBSTRING(CONVERT(NVARCHAR(MAX), @hash), 2, 2))
      

      SQL Server 2012 和 SHA-512

      从 SQL Server 2012 开始,Microsoft 转而使用 SHA-2 512 位:

      hashBytes = 0x0200 | fourByteSalt | SHA512(utf16EncodedPassword+fourByteSalt)
      

      将版本前缀更改为0x0200

      SELECT 
         name, CAST(password AS varbinary(max)) AS PasswordHash
      FROM sys.syslogins
      
      name  PasswordHash
      ----  --------------------------------
      xkcd  0x02006A80BA229556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
      
      • 版本:0200(SHA-2 512 位)
      • 盐:6A80BA22
      • 哈希(64 字节):9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

      这意味着我们对 UTF-16 编码的密码进行哈希处理,并带有 salt 后缀:

      • SHA512("正确的马电池订书钉"+6A80BA22)
      • SHA512(63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500 + 6A80BA22)
      • 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

      【讨论】:

      • 仅供参考,最近版本的 SQL Server 中散列算法发生了变化。见hashcat.net/forum/thread-1474.html
      • 更准确地说是 UTF-16LE(否则 PHP 的 sha1(mb_convert_encoding("...", 'UTF-16')...) 会失败)
      猜你喜欢
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 2015-01-09
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多