我在sql server 2000中有这个查询:
select pwdencrypt('AAAA')
输出加密的'AAAA'字符串:
0x0100CF465B7B12625EF019E157120D58DD46569AC7BF4118455D12625EF019E157120D58DD46569AC7BF4118455D
如何转换(解密)其来源(即'AAAA')的输出?
答案 0 :(得分:19)
SQL Server密码哈希算法:
hashBytes = 0x0100 | fourByteSalt | SHA1(utf16EncodedPassword+fourByteSalt)
例如,要散列密码“正确的马电池主食”。首先,我们生成一些随机盐:
fourByteSalt = 0x9A664D79;
然后将密码(以UTF-16编码)与salt一起散列:
SHA1("correct horse battery staple" + 0x9A66D79);
=SHA1(0x63006F007200720065006300740020006200610074007400650072007900200068006F00720073006500200073007400610070006C006500 0x9A66D79)
=0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
syslogins
表中存储的值是以下内容的串联:
[header] + [salt] + [hash]
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);
将出现相同的哈希,并且您知道密码是正确的。
1999年在SQL Server 7中引入的散列算法在1999年表现良好。
但是今天它已经过时了。它只运行哈希一次,它应该运行几千次,以阻止暴力攻击。
事实上,微软的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开始,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 256位) 6A80BA22
9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
这意味着我们使用salt后缀散列UTF-16编码的密码:
6A80BA22
)63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500
+ 6A80BA22
)9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
答案 1 :(得分:16)
我相信pwdencrypt正在使用哈希,因此你无法真正反转哈希字符串 - 算法的设计是不可能的。
如果您要验证用户输入常用技术的密码是哈希值,然后将其与数据库中的哈希版本进行比较。
这是验证usered输入表的方法
SELECT password_field FROM mytable WHERE password_field=pwdencrypt(userEnteredValue)
将userEnteredValue替换为(大惊喜)用户输入的值:)
答案 2 :(得分:12)
你意识到你可能正在为自己的后背制造一根杆。 pwdencrypt()和pwdcompare()是未记录的函数,在SQL Server的未来版本中可能表现不同。
在点击数据库之前,为什么不使用SHA-2或更好的可预测算法来对密码进行散列?
答案 3 :(得分:4)
你不应该真正解密密码。
您应该加密输入到您的应用程序中的密码,并与数据库中的加密密码进行比较。
编辑 - 如果这是因为忘记了密码,请设置机制以创建新密码。
答案 4 :(得分:1)
您无法再次解密此密码,但还有另一种名为“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
答案 5 :(得分:1)
快速google表示pwdencrypt()不是确定性的,您的语句select pwdencrypt('AAAA')会在我的安装中返回不同的值!
另见本文http://www.theregister.co.uk/2002/07/08/cracking_ms_sql_server_passwords/