2011-04-27 107 views
2

我开发了一个使用ASP.NET成员资格的网站。根据以前网站的评论,我决定加密密码,以便忘记密码的用户可以恢复密码。将ASP.NET成员密码从加密转换为哈希

但是,新的网站(现在有500多个注册用户)给我带来了一些批评,认为行业标准确实是哈希密码。

但是,经过相当广泛的搜索后,我一直无法找到有关如何将现有用户的密码从加密转换为散列的任何内容。

我知道我可以更改web.config文件,并且新用户的密码将使用新格式。但它无法更新现有用户。

注意:我以前提过类似的问题,但大多只是争论哪个更好,加密或散列。我已经过了那次讨论,但我一直无法找到一种方法来转换它们,而不会丢失已经注册的数百个用户。

回答

1

恕我直言,格雷格对你以前的问题(Changing passwordFormat from Encrypted to Hashed)的回应(和相关评论)是要走的路。从本质上讲,你想:

  1. 添加散列成员提供
  2. 遍历所有的加密密码的用户,
  3. 对于每一个解密密码,创建哈希,存储,删除来自数据库的加密版本,然后继续。

完成后,所有加密的密码用户应转换为散列。

+0

您是否看到我对Greg的最终评论?我基本上完成了他的建议,但最终我显然错过了一些东西。不幸的是,他没有回应那个评论,并在那里结束。我想这足够让我不知道ASP.NET成员身份,因为我无法做到这一点。 – 2011-04-27 03:02:54

+0

当你说“存储它”时,这是什么意思?通过会员提供商还是直接?我不清楚如何在不丢失现有数据的情况下做到这一点。你如何玩弄多个提供商并指定哪些是做什么的? – 2011-04-27 03:05:43

+0

这个想法是,你想*丢失现有的数据(加密的密码)。根据上一篇文章中的评论,您希望使用MembershipUser.GetPassword()从加密提供程序获取当前密码。这是可能的,因为您正在使用可逆加密 - 该方法不适用于散列提供者)。一旦你有解密的密码,你想散列它(用盐)。这是一个单向过程。然后使用散列成员资格提供程序(实际上用散列覆盖加密密码)存储密码的结果散列。 (续) – 2011-04-27 19:41:19

1

也许我在这里错过了一些东西,但它应该很简单。创建一个进程来解密密码,然后相应地加盐,并将salt +用户的解密密码的哈希存储在数据库中。显然你不想散列用户的加密密码。不要忘记储存盐。

+0

只是为了澄清,你应该把盐放在密码的末尾,而不是之前,当你散列它。我相信默认情况下,ASP.NET Auth使用SHA1。 – kappasims 2011-04-27 02:41:27

+0

我在概念上知道需要做什么。我想有足够的关于ASP.NET成员资格,我不清楚一些具体细节。 – 2011-04-27 03:01:28

+0

(我只是为“加密”值输入乱码)。 用户“kappasims”,密码“测试”。加密密码:83 @#!s34。解密密码“测试”。解密83 @#!s34以获得“测试”。生成随机盐:“12345”。然后连接成“test12345”。使用SHA1将“test12345”散列为“!@ 83104234!@#$ @#”。存储“!@ 83104234!@#$ @#”作为散列,“12345”作为盐。泡沫。冲洗。重复。 – kappasims 2011-04-27 03:05:45

3

看来您已经知道如何解密密码并更改web.config文件,但您仍然坚持如何实施其余的过程。

使用ILSpy,这里是如何生成每个用户的盐:

byte[] array = new byte[16]; 
new RNGCryptoServiceProvider().GetBytes(array); 
return Convert.ToBase64String(array);  

一旦你有盐,这里是如何生成的密码:

byte[] bytes = Encoding.Unicode.GetBytes(pass); 
byte[] array = Convert.FromBase64String(salt); 
byte[] array2 = new byte[array.Length + bytes.Length]; 
Buffer.BlockCopy(array, 0, array2, 0, array.Length); 
Buffer.BlockCopy(bytes, 0, array2, array.Length, bytes.Length); 
using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { 
    return Convert.ToBase64String(sha1.ComputeHash(array2)); 
} 

其中pass是平纹文本密码你计算,而salt是在上面第一个代码片段中计算的字符串。 default algorithm is SHA1,如果你想知道为什么它被使用。

,因为这是一个一次性的过程,我会写一个HTTP处理程序执行期间很短,计划的维护期间手动更新数据库 - 希望你有这样的奢侈。 (显然先进行备份和测试)。您需要更新的aspnet_Membership表中的以下字段:

  1. Password - 1
  2. PasswordSalt - - 上述
  3. PasswordFormat计算上述

计算从来没有做过这样的事,但希望这会让你开始:)

+0

很酷。我无法马上得到,但看起来像一个好的开始。 (顺便说一句,很高兴听到ILSpy的消息,现在我们需要这个Red Gate已经获得了.NET Reflector!) – 2011-04-27 14:33:40

+0

实际上Red Gate在很久以前就已经获得了.NET Reflector,并且一切都很好 - 直到他们[决定变得讨厌]( http://kuujinbo.info/cs/dotnetReflectorIsDead.aspx)。 – kuujinbo 2011-04-27 22:41:31

+0

是的,我知道。但从那以后,该产品一直是一个越来越大的痛苦。 – 2011-04-27 22:52:12