【问题标题】:How to use Bcrypt to encrypt passwords in Django如何在 Django 中使用 Bcrypt 加密密码
【发布时间】:2015-11-25 02:43:53
【问题描述】:

我正在尝试使用 Bcrypt 来加密用户在注册时提供的密码,然后使用 Bcrypt 来验证用户在登录时提供的密码与存储在数据库中的散列版本。

有一些关于如何通过 Django docs 安装 Bcrypt 的非常好的文档,但它们实际上并没有向您展示如何使用 Bcrypt 来散列密码或使用其他命令。

您需要从某个地方导入 Brcrypt 吗?如果是这样,它的正确语法是什么?散列密码和比较散列密码与非散列密码的语法是什么?

我在 settings.py 文件中安装了 Bcrypted 库,还通过 pip 安装了 Bcrypt。我还需要做什么才能使用 Bcrypt?

【问题讨论】:

    标签: python django encryption bcrypt


    【解决方案1】:

    在你的链接:

    用户对象密码属性是这样格式的字符串:

    <algorithm>$<iterations>$<salt>$<hash> 这些是使用的组件 用于存储用户密码,以美元符号字符分隔 包括:散列算法、算法数量 迭代次数(工作因子)、随机盐和生成的密码 哈希。该算法是许多单向哈希或密码之一 Django 可以使用的存储算法;见下文。迭代描述了 算法在哈希上运行的次数。盐是随机的 使用种子,哈希是单向函数的结果。


    我在 settings.py 文件中安装了 Bcrypted 库... 我还需要做什么才能使用 Bcrypt?

    我不确定第一句话是什么意思。您需要将以下内容放入settings.py

    PASSWORD_HASHERS = (
        'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
        'django.contrib.auth.hashers.BCryptPasswordHasher',
        'django.contrib.auth.hashers.PBKDF2PasswordHasher',
        'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
        'django.contrib.auth.hashers.SHA1PasswordHasher',
        'django.contrib.auth.hashers.MD5PasswordHasher',
        'django.contrib.auth.hashers.CryptPasswordHasher',
    )
    

    使用 Bcrypt 验证用户在登录时提供的密码 存储在数据库中的哈希版本。

    您可以手动完成:

    django.contrib.auth.hashers 模块提供了一组函数来 创建和验证散列密码。您可以独立使用它们 来自用户模型。

    check_password(密码,编码)
    如果您想通过将纯文本密码与哈希密码进行比较来手动验证用户身份 数据库中的密码,使用便利功能 检查密码()。它有两个参数:纯文本密码 检查,以及数据库中用户密码字段的完整值 进行检查,如果匹配则返回 True,否则返回 False。

    https://docs.djangoproject.com/en/1.9/topics/auth/passwords/#module-django.contrib.auth.hashers

    或者,您可以使用authenticate()

    验证(**凭据)
    要验证给定的用户名和密码,请使用 authenticate()。它采用以下形式的凭据 关键字参数,对于默认配置,这是用户名和 密码,如果密码有效则返回一个用户对象 给定的用户名。如果密码无效,则 authenticate() 返回 没有任何。示例:

    from django.contrib.auth import authenticate
    
    user = authenticate(username='john', password='password to check')
    
    if user is not None:
        # the password verified for the user
        if user.is_active:
            print("User is valid, active and authenticated")
        else:
            print("The password is valid, but the account has been disabled!")
    else:
        # the authentication system was unable to verify the username and password
        print("The username and password were incorrect.")
    

    https://docs.djangoproject.com/en/1.9/topics/auth/default/#authenticating-users

    这里有一些例子:

    (django186p34)~/django_projects/dj1$ python manage.py shell
    
    Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03) 
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    
    >>> from django.conf import settings
    >>> print(settings.PASSWORD_HASHERS)
    
    ('django.contrib.auth.hashers.PBKDF2PasswordHasher',
     'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
     'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
     'django.contrib.auth.hashers.BCryptPasswordHasher',
     'django.contrib.auth.hashers.SHA1PasswordHasher',
     'django.contrib.auth.hashers.MD5PasswordHasher',
     'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher',
     'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher', 
     'django.contrib.auth.hashers.CryptPasswordHasher')
    

    这些是默认值:在我的 settings.py 中没有PASSWORD_HASHERS 的条目。

    >>> from django.contrib.auth.models import User
    
    >>> my_user = User.objects.create_user('ea87', 'ea@gmail.com', '666monkeysAndDogs777')
    
    >>> my_user.save()
    >>> my_user.password
    'pbkdf2_sha256$20000$L7uq6goI1HIl$RYqywMgPywhhku/YqIxWKbpxODBeczfLm5zthHjNSSk='
    >>> my_user.username
    'ea87'
    
    >>> from django.contrib.auth import authenticate
    
    >>> authenticate(username='ea87', password='666monkeysAndDogs777')
    <User: ea87>
    
    >>> print(authenticate(username='ea87', password='wrong password'))
    None
    
    >>> from django.contrib.auth.hashers import check_password
    
    >>> check_password('666monkeysAndDogs777', my_user.password)
    True
    
    >>> exit()
    

    接下来,我在 settings.py 中添加了以下内容:

    PASSWORD_HASHERS = (
        'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
        'django.contrib.auth.hashers.BCryptPasswordHasher',
        'django.contrib.auth.hashers.PBKDF2PasswordHasher',
        'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
        'django.contrib.auth.hashers.SHA1PasswordHasher',
        'django.contrib.auth.hashers.MD5PasswordHasher',
        'django.contrib.auth.hashers.CryptPasswordHasher',
    )
    

    (django186p34)~/django_projects/dj1$ python manage.py shell
    
    Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03) 
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    
    >>> from django.conf import settings
    >>> print(settings.PASSWORD_HASHERS)
    ('django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
     'django.contrib.auth.hashers.BCryptPasswordHasher',
     'django.contrib.auth.hashers.PBKDF2PasswordHasher',
     'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
     'django.contrib.auth.hashers.SHA1PasswordHasher',
     'django.contrib.auth.hashers.MD5PasswordHasher', 
     'django.contrib.auth.hashers.CryptPasswordHasher')
    

    注意元组前面的 bcrypt 哈希。

    >>> from django.contrib.auth.models import User
    
    >>> user = User.objects.get(username='ea87')
    >>> user
    <User: ea87>
    
    >>> user.password
    'pbkdf2_sha256$20000$DS20ZOCWTBFN$AFfzg3iC24Pkj5UtEu3O+J8KOVBQvaLVx43D0Wsr4PY='
    
    >>> user.set_password('666monkeysAndDogs777')
    >>> user.password
    'bcrypt_sha256$$2b$12$QeWvpi7hQ8cPQBF0LzD4C.89R81AV4PxK0kjVXG73fkLoQxYBundW'
    

    可以看到密码已经改成bcrypt版本了。

    【讨论】:

    • 我投了赞成票,因为很多想法帮助我找出让我感到困惑的地方;简而言之,对于那些将来感到困惑的人:BCrypt 产生的哈希(这是 php 当前使用的)根本不是文档中所述的 &lt;algorithm&gt;$&lt;iterations&gt;$&lt;salt&gt;$&lt;hash&gt; 形式,但正如您在答案末尾看到的那样(只是没有“_sha256”,至少我的 php 哈希是这样加密的 -> 导入 django!:))
    【解决方案2】:

    7stud 答案的简短版

    在 Django 1.9 默认模板项目上使用create_user:

    User.objects.create_user(username='uname', password='mypass')
    

    而不是create,它不会散列密码。

    另一个选项是设置密码:

    user = User(username='uname')
    user.set_password('mypass')
    user.save()
    

    最后,您还可以对字符串进行操作,如:How to quickly encrypt a password string in Django without an User Model?

    【讨论】:

      猜你喜欢
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多