是否可以将 40 个字符的 SHA1 哈希转换为 20 个字符的 SHA1 哈希?
Posted
技术标签:
【中文标题】是否可以将 40 个字符的 SHA1 哈希转换为 20 个字符的 SHA1 哈希?【英文标题】:Is it possible to convert a 40-character SHA1 hash to a 20-character SHA1 hash? 【发布时间】:2011-01-28 19:34:27 【问题描述】:我的问题有点毛骨悚然,我可能问错了问题,所以请多多包涵……
我有一个旧的 mysql 数据库,用于存储会员系统的用户密码和盐。这两个值都已使用 Ruby 框架进行哈希处理 - 大致如下:
哈希盐 = 摘要::SHA1.hexdigest("--#Time.now.to_s--#login--")
哈希密码 = 摘要::SHA1.hexdigest("#hashedsalt:#password")
所以这两个值在 MySQL 中都存储为 40 个字符的字符串 (varchar(40))。
现在我需要将所有这些用户导入到一个新网站的 ASP.NET 成员框架中,该网站使用 SQL Server 数据库。据我了解,在我配置 ASP.NET 成员身份的方式中,用户密码和盐也作为 SHA1 哈希值存储在成员身份数据库中(在表 aspnet_Membership 中),然后进行 Base64 编码(有关详细信息,请参阅here)并存储为 nvarchar(128) 数据。
但是从存储的 Base64 编码字符串的长度(28 个字符)来看,ASP.NET 成员生成的 SHA1 哈希似乎只有 20 个字符长,而不是 40 个。从我一直在做的其他一些阅读中,我我认为这与每个字符/字符集/编码或相关的位数有关。
那么有什么方法可以将 40 个字符的 SHA1 哈希转换为 20 个字符的哈希,然后我可以将其传输到新的 ASP.NET 成员数据表中吗?我现在已经非常熟悉 ASP.NET 成员资格,但我觉得我只是错过了这一块。但是,可能也知道 Ruby 中的 SHA1 和 .NET 中的 SHA1 不兼容,所以我正在打一场失败的战斗……
提前感谢您的任何见解。
【问题讨论】:
【参考方案1】:您的 Ruby 应用程序中的 varchar 表示形式似乎是“十六进制字符串”,类似于: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 代码创建的盐渍哈希,与用于存储哈希摘要的编码无关,这是一个完全不同的主题。您可能必须重写自己的成员资格提供程序,此时存储编码变得无关紧要,因为您可以随意存储它们。
【讨论】:
很有趣,我明天要试试这个。非常感谢。【参考方案2】:Ruby 使用 SHA2,而 ASP.NET 使用 SHA1,不,您不能在这些版本之间“转换”。为此,您需要从明文重新计算哈希值。
编辑:SHA 已标准化,因此您可以在 Internet 上搜索 SHA2 库以在 ASP.NET 中使用。
【讨论】:
.net 有一个 SHA1 类:msdn.microsoft.com/en-us/library/…以上是关于是否可以将 40 个字符的 SHA1 哈希转换为 20 个字符的 SHA1 哈希?的主要内容,如果未能解决你的问题,请参考以下文章
将从 SHA1 返回的 unsigned char* 转换为字符串