tl;dr -- 在使用 SQLAlchemy 将密码插入 MySQL 数据库之前,如何使用 Python 端库(如 PassLib)对密码进行哈希处理?
好吧,所以我一直在我的桌子上敲了一两天试图弄清楚这一点,所以它是这样的:
我正在使用 Pyramid/SQLAlchemy 编写一个 Web 应用程序,并且我正在尝试与我的 MySQL 数据库的用户表交互。
最终,我想做以下事情:
将密码与哈希进行比较:
if user1.password == 'supersecret'
插入新密码:
user2.password = 'supersecret'
我希望能够在密码进入数据库之前使用 PassLib 对其进行哈希处理,而且我不太喜欢使用内置的 MySQL SHA2 函数,因为它没有加盐。
但是,只是为了尝试一下,我确实使用 SQL 端函数进行了这项工作:
from sqlalchemy import func, TypeDecorator, type_coerce
from sqlalchemy.dialects.mysql import CHAR, VARCHAR, INTEGER
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
class SHA2Password(TypeDecorator):
"""Applies the SHA2 function to incoming passwords."""
impl = CHAR(64)
def bind_expression(self, bindvalue):
return func.sha2(bindvalue, 256)
class comparator_factory(CHAR.comparator_factory):
def __eq__(self, other):
local_pw = type_coerce(self.expr, CHAR)
return local_pw == func.sha2(other, 256)
class User(Base):
__tablename__ = 'Users'
_id = Column('userID', INTEGER(unsigned=True), primary_key=True)
username = Column(VARCHAR(length=64))
password = Column(SHA2Password(length=64))
def __init__(self, username, password):
self.username = username
self.password = password
这是从http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DatabaseCrypt的示例 2 复制而来的
这样就可以了,并允许我使用内置的 MySQL SHA2 函数(通过调用func.sha2()
)并完全按照我的意愿行事。但是,现在我试图在 Python 端用 PassLib 替换它。
PassLib 提供了两个功能:一个是创建新的密码哈希,另一个是验证密码:
from passlib.hash import sha256_crypt
new_password = sha256_crypt.encrypt("supersecret")
sha256_crypt.verify("supersecret", new_password)
我不太清楚如何实际实现这一点。阅读了所有文档后,我认为它要么是 TypeDecorator 的不同形式,要么是自定义类型声明,要么是混合值,要么是混合属性。我尝试遵循这个,但这对我来说并没有真正意义,也没有实际运行建议的代码。
所以,总结一下我的问题——我如何重载=
and==
运算符,以便它们通过适当的散列函数运行?