Django使用passlib的hasher
项目描述
django-hashers-passlib[-revived]
⚠️ 原始项目 django-hashers-passlib 已停止维护。它已被分叉、更新并重命名为 django-hashers-passlib-revived
。您可能在这里以及代码的各个部分仍然找到术语 django-hashers-passlib
。
django-hashers-passlib-revived
的目的是使 passlib 提供的密码散列方案在 Django 中可用。与 passlib 的 passlib.ext.django 不同,它不替换 Django 的 密码管理系统,而是提供标准散列器,可以添加到 PASSWORD_HASHERS
设置以使用 passlib 提供的散列方案。
此模块有两个主要用途
- 您希望从现有的应用程序中导入密码散列到您的Django数据库。
- 您希望在将来将密码散列导出到不同的应用程序。
安装
此模块可通过pip获取,使用以下命令安装:
pip install django-hashers-passlib-revived
兼容性矩阵
Py/Dj | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 |
---|---|---|---|---|---|
3.2 (LTS) | ✓ | ✓ | ✓ | ✓ | ✓ |
4.0 | ✓ | ✓ | ✓ | ✓ | ✓ |
4.1 | ✓ | ✓ | ✓ | ✓ | ✓ |
4.2 (LTS) | — | — | ✓ | ✓ | ✓ |
5.0 | — | — | ✓ | ✓ | ✓ |
此外,passlib>=1.7"
是依赖项。
入门
此模块支持passlib支持的几乎所有散列(某些散列最初必须进行转换 - 见下文)。如果要让您的Django项目应用理解passlib提供的散列,只需将散列器添加到PASSWORD_HASHERS设置中。请注意,第一个值是默认散列器,因此如果您想将这些散列之一存储为新用户密码,请将散列添加到列表的开头
PASSWORD_HASHERS = [
# new user passwords should be stored in the phpass format
'hashers_passlib.phpass',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
# ... other Django hashers
# We also want to add some users from say mssql2000 (who wouldn't?)
'hashers_passlib.mssql2000',
]
几乎每个passlib模块都有一个与名称相同的散列器,有关完整列表,请参阅“支持的散列”。
您还可以为不同的散列算法配置默认参数,例如配置不同轮次的pbkdf2_sha256
PASSLIB_KEYWORDS = {
'pbkdf2_sha256': {
'rounds': 32000,
},
}
passlib的文档包含可用参数的列表。
导入/导出
Django规定了存储密码的方案(见Django如何存储密码。某些散列仅通过添加散列名称来存储,其他散列几乎适合该方案,只需移除其前面的$
。
如果您想从其他应用程序导入散列到Django的散列编码方案(有关详细信息,请参阅下文“内部工作方式”),每个散列器都有一个from_orig()
和to_orig()
方法,这允许导入/导出散列。因此,从不同的系统导入用户只是调用正确散列器的from_orig()
并将其保存到Django的User
模型的password
字段。以下是一个简单的示例
# Lets import a phpass (WordPress, phpBB3, ...) hash. This assumes that you have 'hashers_passlib.phpass' in
# your PASSWORD_HASHERS setting.
from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import get_hasher
User = get_user_model() # get any custom user model
hasher = get_hasher('phpass')
# you got this from i.e. a WordPress database:
raw_hashes = {
'joe': '$P$EnOjUf5ie1AeWMHpw1dqHUQYHAIBe41',
'jane': '$P$E6UROQJscRzZ3ve2hoIFZ1OcjBA1W10',
}
for username, hash in raw_hashes.items():
user = User.objects.create(username=username)
user.password = hasher.from_orig(hash)
user.save()
现在,“joe”和“jane”可以使用他们的旧用户名和密码登录。
如果您想再次将具有phpass散列的用户导出到WordPress数据库,您可以简单地获取原始散列(为了简单起见,我们在这里将所有内容打印到stdout)
from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import get_hasher
User = get_user_model() # get any custom user model
hasher = get_hasher('phpass')
for user in User.objects.filter(password__startswith='phpass$'):
orig_hash = hasher.to_orig(user.password)
print('%s has hash "%s"' % (user.username, orig_hash))
支持的散列
此模块为passlib提供的几乎所有散列方案提供了散列器 - 但请记住,您必须首先使用散列器的from_orig()
方法导入它们才能使用。某些散列必须首先进行转换(见下文),并且不支持少数几个旧的散列。所有密码散列器都具有与它们包装的passlib散列器相同的类名,并位于hashers_passlib
模块中。因此,要启用对例如sha1_crypt
散列的支持,请将hashers_passlib.sha1_crypt
添加到您的PASSWORD_HASHERS
Django设置中。
警告:某些散列的长度超过了Django提供的标准用户模型中的128个字符。您必须指定一个至少有256个字符的自定义用户模型(对于hex_sha512
、pbkdf2_sha512
、scram
和sha512_crypt
)或至少有384个字符的(对于grub_pbkdf2_sha512
)。
以下算法受到支持:des_crypt、bsdi_crypt、bigcrypt、crypt16、md5_crypt、sha1_crypt、sun_md5_crypt、sha256_crypt、sha512_crypt、apr_md5_crypt、bcrypt_sha256、phpass、pbkdf2_<digest>、dlitz_pbkdf2_sha1、cta_pbkdf2_sha1、scram、ldap_salted_md5、ldap_salted_sha1、atlassian_pbkdf2_sha1、fshp、mssql2000、mssql2005、mysql323、mysql41、oracle11、lmhash、nthash、cisco_pix、cisco_type7、grub_pbkdf2_sha512、hex_{md4,sha256,sha512}、argon2 和 scrypt
大多数哈希将以简单的前缀 <algorithm>$
保存,其中 "<algorithm>" 是散列器的名称。唯一的例外是一些哈希(apr_md5_crypt
、bcrypt_sha256
、pbkdf2_<digest>
、scram
),它们几乎已经符合 Django 的哈希方案,只需去掉开头的 $
。
注意:一些哈希(bcrypt_sha256
、pbkdf2_<digest>
、...)看起来与 Django 提供的非常相似,但实际上是不同的算法。
通过转换支持的哈希
有些哈希方案实际上只是不同哈希方案的微小变化。例如,bsd_nthash 只是一个普通的 nthash,前面加上 $3$$
,而 ldap_md5 只是前面加上 {MD5}
的纯 MD5 哈希,这已经由 Django 支持。
为了避免代码重复,此模块不提供这些方案的密码散列器,而是在 hashers_passlib.converters
下提供转换器。转换后的哈希可以被不同的散列器或 Django 提供的散列器读取。
如果您想导入 bsd_nthash
哈希,您可以通过手动删除标识符或使用转换器来实现。
# Lets import bsd_nthash hashes as plain nthash hashes. This assumes you have
# have 'hashers_passlib.nthash' in your PASSWORD_HASHERS setting.
from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import get_hasher
from hashers_passlib.converters import bsd_nthash
conv = bsd_nthash()
raw_hashes = {
'joe': '$3$$baac3929fabc9e6dcd32421ba94a84d4',
}
for username, hash in raw_hashes.items():
user = User.objects.create(username=username)
# convert bsd_nthash to plain nthash:
user.password = converter.from_orig(hash)
user.save()
以下转换器在 hashers_passlib.converters
下可用,它们可用于从原始方案转换为其他方案
从 | 到 | 说明 |
---|---|---|
bcrypt | BCryptPasswordHasher |
转换为 Django 散列器支持的 bcrypt 哈希。 |
bsd_nthash | nthash |
从 bsd_nthash 转换到 nthash,反之亦然。 |
ldap_md5 | UnsaltedMD5PasswordHasher |
转换为 Django 支持的纯 MD5 哈希。 |
ldap_sha1 | UnsaltedSHA1PasswordHasher |
转换为 Django 支持的纯 SHA1 哈希。 |
ldap_hex_md5 | UnsaltedMD5PasswordHasher |
转换为 Django 支持的纯 MD5 哈希。 |
ldap_hex_sha1 | UnsaltedSHA1PasswordHasher |
转换为 Django 支持的纯 SHA1 哈希。 |
ldap_{crypt} | 各种 | 转换为它们的非LDAP对应项(例如,ldap_des_crypt 转换为普通的 des_crypt 哈希)。 |
ldap_bcrypt | BCryptPasswordHasher |
与其他 ldap_{crypt} 方案不同,ldap_bcrypt 哈希被转换为 Django 自带的 BCrypt 哈希器所理解的格式。 |
ldap_pbkdf2_{digest} | pbkdf2_{digest} |
转换为它们的非LDAP对应项。 |
不受支持的哈希
某些哈希不受支持,因为它们需要用户名来生成盐: postgres_md5, oracle10, msdcc 和 msdcc2。
内部工作原理
Django 的密码管理系统以与 passlib 所称的 模块化加密格式非常相似但仍有区别的格式存储密码
<algorithm>$<content>
... 其中 "<algorithm>" 是用于选择应处理哈希的哈希器类的标识符。与模块化加密格式的唯一区别是它缺少前导的 $
符号。注意,中间的 $
是一个强制分隔符。
此模块修改哈希方案,以便在将其存储到数据库之前符合此方案。这些修改是完全可逆的——实际上,此模块依赖于可逆性,我们的哈希器不会以任何其他方式工作。根据原始哈希方案,哈希以以下几种方式之一进行修改
- 一些旧的、不安全的哈希需要用户名来编码哈希。Django 的哈希器不接收用户名,因此它们与该模块不兼容,也不受支持。
- Passlib 的一些哈希已经由 Django 支持,并且此处没有重复功能。
- 一些哈希方案实际上是不同方案的微小修改,我们在此情况下提供转换器。
- 一些哈希已经几乎符合 Django 的方案,并且具有相当独特的标识符,它们只是去除了前导的
$
。 - 所有其他哈希(占绝大多数!)只是添加了
<identifier>$
。这与 Django 对 bcrypt 哈希的处理方式相同。
本地开发
使用 Poetry 安装项目和其开发依赖项
pip install poetry
poetry install
您可以使用 pytest 调用测试套件
poetry run pytest
您可以使用 Tox 测试所有支持的 Django 和 Python 版本组合
pip install tox
tox p
变更日志
2.0 (WIP)
原始项目 django-hashes-passlib 已由原始开发者停止维护。该项目已被分叉并重命名为 django-hashers-passlib-revived
- 添加了对 Django 4.1、4.2 和 5.0 的支持。
- 添加了对 Python 3.11 和 3.12 的支持。
- 为所有内容添加了类型。
- 使用 Poetry 为本地开发环境。
- 总体代码清理和现代化。
1.0.0 (从未发布)
- 添加了对 Django 3.2 和 Django 4.0 的支持。
- 添加了对 Python 3.7 - 3.10 的支持。
- 放弃了对过时 Django 版本 1.8、1.10 和 1.11 的支持。
- 放弃了对已弃用的 Python 版本(2.7 - 3.6)的支持。
- 添加了
argon2d
和argon2id
哈希器。我们建议如果需要,添加所有 argon2 哈希器。 - 将 CI 测试切换到 GitHub Actions。
- 现代化项目设置(
pyproject.toml
、setup.cfg
等)。 - 将 black 和 pylint 添加到 linters/formatters 套件。
0.4 (2017年11月19日)
- 支持 passlib 1.7。
- 添加了 argon2 和 scrypt 哈希器。
- 通过 PASSLIB_KEYWORDS 设置配置哈希参数。
- 添加了类似于 Django 的
VERSION
和get_version()
。 - 通过 Travis 集成运行测试套件,使用 Python 2.7、3.4+ 以及 Django 当前所有支持的版本。
- 更新 setup.py 中的 python 版本分类器。
- 还上传了 wheel。
0.3 (2015年12月5日)
- 要求
Python3>=3.4
。 - 依赖于
Django>=1.8
。 - 更新 passlib 和 bcrypt 依赖项。
0.2 (2014年3月22日)
- 删除 distribute_setup.py。
- 为所有哈希器实现通用的
safe_summary()
方法。 - 将 bcrypt 添加到 requirements.txt。
- 现在向 setup.py 报告的版本与从 git 仓库执行时相同的
git describe
。 - 添加
version
setup.py 命令。 - 修复 Python 3 中的
ldap_md5
和ldap_sha1
转换器。
0.1 (2014年1月1日)
- 初始发布。
项目详情
django_hashers_passlib_revived-2.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 530904d2072db492f00565e351356e9e8409a2059b3c18f7cd1c239a9920d355 |
|
MD5 | 09ed55b9de29803fcae6b40876f90f9e |
|
BLAKE2b-256 | 0191bb2708b929e9d7f9894c920752eea48943e4c88c4c8d5d5d09b8505e5e15 |
django_hashers_passlib_revived-2.0-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7656ce47fb0fecb89157f8c7790a93acec28226360c533a42dedb72c706849c0 |
|
MD5 | 079bfad7e77b3270abe9eedf527dcb06 |
|
BLAKE2b-256 | 712ab792e9c73a7eeb3945b3b099f7f3cd7eb4166abbe7b20c4bbc926a3dbab6 |