将ASP.NET成员资格用户迁移到Django而不重置密码?

时间:2011-01-27 12:19:51

标签: asp.net django hash membership sha1

我有一个部分由其他人编写的系统,对于这么小的应用来说,这是一个完整的维护噩梦。我终于得到了改变,这些改变证明了重写可怕的混乱,所以我把它移到了Django。

在我采取行动之前,我一直试图将密码哈希和盐移到Django auth表[sha1] $ [salt] $ [hash]但是无法正确地进行哈希(重置密码)不是一个真正的选择。)

以下是我迄今为止所能找到的内容:

  • ASP.NET将哈希存储为base64字符串并使用base64 salt(哈希值之前)
  • 我显然可以将base64哈希值转换为字节数组
  • Django使用hexdigest,我尝试了BitConverter.ToString,但它们的哈希方式不同

我在这里打败了吗?在Django中编写一个方法,以便像ASP.NET那样进行散列会更好吗?

任何帮助表示赞赏,

托马斯

2 个答案:

答案 0 :(得分:3)

这里唯一可以避免密码重置的实际选项是:

  1. 编写哈希转换算法,将Asp.Net哈希值转换为hexdigest哈希值。祝你好运。如果你把它拉下来,请写一篇关于它的文章。
  2. 重写Django散列算法,使其与Asp.Net算法完全相同。这个应该是最容易实现的,但它仍然会在此过程中遇到陷阱和陷阱。
  3. 您也可以尝试对密码进行反向工程,但如果您成功完成此操作,则会使散列算法无意义IMO。

答案 1 :(得分:2)

使用以下Django密码hasher创建一个新模块来处理ASP.net(sha1)密码:

import hashlib
import base64

from django.contrib.auth.hashers import (BasePasswordHasher, mask_hash)
from django.utils.datastructures import SortedDict
from django.utils.encoding import force_bytes
from django.utils.crypto import constant_time_compare
from django.utils.translation import ugettext_noop as _

def utf16tobin(s):
    return s.encode('hex')[4:].decode('hex')

class MSSHA1PasswordHasher(BasePasswordHasher):
    """
    ASP.NET hasher
    """
    algorithm = "mssha1"

    def encode(self, password, salt):
        assert password is not None
        assert salt and '$' not in salt
        pwdenc = password.encode('utf16')
        pwdenc = utf16tobin(pwdenc)
        saltdecode = base64.b64decode(salt)
        m = hashlib.sha1()
        m.update(saltdecode)
        m.update(pwdenc)
        hash = base64.b64encode(m.digest())
        return "%s$%s$%s" % (self.algorithm, salt, hash)

    def verify(self, password, encoded):
        algorithm, salt, hash = encoded.split('$', 2)
        assert algorithm == self.algorithm
        encoded_2 = self.encode(password, salt)
        return constant_time_compare(encoded, encoded_2)

    def safe_summary(self, encoded):
        algorithm, salt, hash = encoded.split('$', 2)
        assert algorithm == self.algorithm
        return SortedDict([
            (_('algorithm'), algorithm),
            (_('salt'), mask_hash(salt, show=2)),
            (_('hash'), mask_hash(hash)),
            ])

将模块名称添加到PASSWORD_HASHERS列表中的设置文件中(有关详细信息,请参阅https://docs.djangoproject.com/en/1.4/topics/auth/)。

将ASP.net salt和密码迁移到Django密码字段中,如下所示:

user.password = "mssha1$" + old_membership.passwordsalt + "$" + old_membership.password

然后,用户可以使用现有的ASP.net密码登录您的Django应用程序。一旦他们成功登录,Django将自动将他们的密码升级到最新的算法,例如, PBKDF2。