关于SQL内置MD5加密函数的怪异有关问题
关于SQL内置MD5加密函数的怪异问题
我数据据结构:
id, username ,turepass ,password
原先的密码都是明文密码,放在turepass中,
现在要求把密码用MD5加密后放在password中。
网友有讲到用substring(sys.fn_sqlvarbasetostr(HashBytes('MD5','123456')),11,16),可以得到16位密码。
但我在使用时却发现不行:
我用的语句是:
UPDATE [z_user] SET password =substring(sys.fn_sqlvarbasetostr(HashBytes('MD5',[turepass])),11,16) where id=7103683
结果密码并不等于turepass的字段加密后的密码,而且是个很怪的,查不出来的密码。
为了验证密码是否出错了,我用这个:
SELECT
[id] ,
turepass,
substring(sys.fn_sqlvarbasetostr(HashBytes('MD5',[turepass])),11,16),
substring(sys.fn_sqlvarbasetostr(HashBytes('MD5','xljian2002')),11,16) ,
FROM [mm].[dbo].[z_user] where id=7103683
7103683行存放的数据:
id=7103683
turepass=xljian2002
最后到的结果是:
id turepass (无列名) (无列名)
7103683 xljian2002 4f55f145f00da513 9aa9d862808778c0
其中9aa9d862808778c0是xljian2002这个字符串加密后的正确密码。
我想问一下,substring(sys.fn_sqlvarbasetostr(HashBytes('MD5',[turepass])),11,16), 为何不对??
------解决思路----------------------
下面举个例子,类型为char,两个hash值就不同了:
------解决思路----------------------
你试试cast(turepass as varchar(100)),然后计算hash值
------解决思路----------------------
MD5 是处理字节数组的算法。
即使某些函数可以直接处理字符串,内部也有一个隐式的字符串到字节数组的转换,而根据编码不同,转换出来的字节数组也不同,所以计算结果会不一样。
既然数据类型是 nvarchar,就用 UNICODE 编码好了。
前台程序不需要计算 MD5 的,直接传入密码xljian2002查询,如果密码错误返回记录数为0。
------解决思路----------------------
我的意思是既然用Unicode编码 (nvarchar) 可以求md5,为什么非得用Ascii编码(varchar)求md5,难道前者不是md5了?
密码求得md5的唯一用途也就是判断密码是否正确时用md5是否相等来判断,所以都用Unicode编码的md5比较不可以吗?难道只有Ascii编码的md5才能比较?
我数据据结构:
id, username ,turepass ,password
原先的密码都是明文密码,放在turepass中,
现在要求把密码用MD5加密后放在password中。
网友有讲到用substring(sys.fn_sqlvarbasetostr(HashBytes('MD5','123456')),11,16),可以得到16位密码。
但我在使用时却发现不行:
我用的语句是:
UPDATE [z_user] SET password =substring(sys.fn_sqlvarbasetostr(HashBytes('MD5',[turepass])),11,16) where id=7103683
结果密码并不等于turepass的字段加密后的密码,而且是个很怪的,查不出来的密码。
为了验证密码是否出错了,我用这个:
SELECT
[id] ,
turepass,
substring(sys.fn_sqlvarbasetostr(HashBytes('MD5',[turepass])),11,16),
substring(sys.fn_sqlvarbasetostr(HashBytes('MD5','xljian2002')),11,16) ,
FROM [mm].[dbo].[z_user] where id=7103683
7103683行存放的数据:
id=7103683
turepass=xljian2002
最后到的结果是:
id turepass (无列名) (无列名)
7103683 xljian2002 4f55f145f00da513 9aa9d862808778c0
其中9aa9d862808778c0是xljian2002这个字符串加密后的正确密码。
我想问一下,substring(sys.fn_sqlvarbasetostr(HashBytes('MD5',[turepass])),11,16), 为何不对??
------解决思路----------------------
下面举个例子,类型为char,两个hash值就不同了:
--drop table [z_user]
create table [z_user] (id numeric,[turepass] char(30))
insert into [z_user]
values(7103683,'xljian2002')
SELECT
[id] ,
turepass,
HashBytes('MD5',[turepass]),
HashBytes('MD5',
'xljian2002')
FROM [z_user] where id=7103683
id turepass (无列名) (无列名)
7103683 xljian2002 0x46139C5E42D4E67B52F4B37E0B68AE7B 0xFABA65999AA9D862808778C06B496356/*
*/
------解决思路----------------------
你试试cast(turepass as varchar(100)),然后计算hash值
------解决思路----------------------
MD5 是处理字节数组的算法。
即使某些函数可以直接处理字符串,内部也有一个隐式的字符串到字节数组的转换,而根据编码不同,转换出来的字节数组也不同,所以计算结果会不一样。
既然数据类型是 nvarchar,就用 UNICODE 编码好了。
前台程序不需要计算 MD5 的,直接传入密码xljian2002查询,如果密码错误返回记录数为0。
SELECT *
FROM [mm].[dbo].[z_user]
where id=7103683
AND [password] = substring(sys.fn_sqlvarbasetostr(HashBytes('MD5','xljian2002')),11,16)
------解决思路----------------------
我的意思是既然用Unicode编码 (nvarchar) 可以求md5,为什么非得用Ascii编码(varchar)求md5,难道前者不是md5了?
密码求得md5的唯一用途也就是判断密码是否正确时用md5是否相等来判断,所以都用Unicode编码的md5比较不可以吗?难道只有Ascii编码的md5才能比较?