是否可以将40个字符的SHA1哈希转换为20个字符的SHA1哈希?

问题描述:

我的问题是有点毛茸茸的,我可能会问错了问题,所以请多多包涵......是否可以将40个字符的SHA1哈希转换为20个字符的SHA1哈希?

我有一个存储用户密码&盐为会员制的传统MySQL数据库。这两个值都被使用Ruby框架散列 - 大致是这样的:

hashedsalt = 文摘:: SHA1.hexdigest(“ - #{Time.now.to_s} - #{登录} - - “)

hashedpassword = 文摘:: SHA1.hexdigest(” #{hashedsalt}:#{密码}“)

所以这两个值被存储为40个字符的字符串(VARCHAR(40) )在MySQL中。

现在我需要将所有这些用户导入到新成员网站的ASP.NET成员资格框架中,该网站使用SQL Server数据库。我的理解是,我配置ASP.NET成员资格的方式,用户密码和salt也存储在成员资格数据库(在表aspnet_Membership中)作为SHA1哈希值,然后进行Base64编码(有关详细信息,请参见here)并存储作为nvarchar(128)数据。

但是,从存储的Base64编码字符串的长度(28个字符)看来,ASP.NET成员资格生成的SHA1哈希长度只有20个字符,而不是40个。从其他阅读中我一直在做我认为这与每个字符/字符集/编码或相关的位数有关。

那么有什么方法可以将40个字符的SHA1哈希值转换为20个字符的哈希值,然后我可以将其转换为新的ASP.NET成员资格数据表?我现在对ASP.NET成员非常熟悉,但我觉得我只是缺少这一块。然而,也可能知道Ruby中的SHA1和.NET中的SHA1不兼容,所以我正在为一场失败的战斗而战......

在此先感谢您的任何见解。

Ruby应用程序中的varchar表示看起来像是'hex as string',如下所示:01AB02EF...23EF。也就是说,每个字节都表示为从00到FF的一对字符,即字节的十六进制值。因此SHA哈希(20个字节)被表示为40个字符。如果散列值是(0,1,2,...),则字符串将是000102. ASP base64是实际字节的base64编码。所以你需要做的就是获取MySQL字符并获取相应的字节,然后将它们编码为base64。

实际上,你可以做转型SQL本身:

declare @x varchar(40); 
set @x = '000102030405060708090A0B0C0D0E0F10111213'; 

declare @sql nvarchar(max); 
set @sql = N'set @out=0x' + @x; 

declare @out varbinary(20); 
exec sp_executesql @sql, N'@out varbinary(20) output', @out output; 
select @out for xml path(''); 

但强迫你的ASP.Net成员资格提供使用盐渍哈希Ruby代码中创建的,不相关的用于存储哈希摘要的编码,这是一个完全不同的话题。您可能必须重新编写自己的会员供应商,此时存储编码变得无关紧要,因为您可以随意存储它们。

+0

非常有趣,我将在明天尝试这个。非常感谢。 – ewitch 2010-03-17 23:29:56

Ruby使用SHA2,而ASP.NET使用SHA1,否则不能在这些版本之间“转换”。为此,您需要重新计算纯文本中的哈希值。

编辑:SHA已经标准化,因此您可以在Internet上搜索在ASP.NET中使用的SHA2库。

+0

.net有一个SHA1类:http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx – 2010-03-17 22:58:22