You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中重实现Microsoft SQL Server的PWDENCRYPT/PWDCOMPARE?

Django自定义密码哈希器适配SQL Server PWDENCRYPT哈希验证

我们团队近期用Python+Django重构原有的.NET平台,上线前要迁移用户数据。原系统依赖SQL Server自带的PWDENCRYPT生成密码哈希、PWDCOMPARE做验证,为了让用户不用重置密码就能直接登录,必须实现一个自定义Django密码哈希器来兼容这套逻辑。

一开始查微软官方文档,发现PWDENCRYPT的底层实现几乎没有详细说明,还被标记为旧版函数,明确说未来可能弃用,推荐使用支持更多算法的HASHBYTES。翻了不少相关内容找思路,但部分解释和示例存在错误,绕了好多弯路,甚至一度想放弃。后来同事找到了关键突破口——密码必须先转换为UTF-16LE编码,这对熟悉Windows环境的人来说可能是常识,但我们一开始完全忽略了这个细节。

下面是最终可用的自定义哈希器代码,直接集成到Django项目即可:

from django.contrib.auth.hashers import BasePasswordHasher
import hashlib
import os

class MSSQLPWDENCRYPTHasher(BasePasswordHasher):
    algorithm = "mssql_pwdencrypt"

    def verify(self, password, encoded):
        # SQL Server的PWDENCRYPT哈希格式:0x0100 + 4字节salt + 20字节MD5哈希值
        encoded_hex = encoded[2:]  # 移除开头的0x前缀
        encoded_bytes = bytes.fromhex(encoded_hex)
        
        # 提取salt和存储的哈希值
        salt = encoded_bytes[1:5]
        stored_hash = encoded_bytes[5:25]

        # 按规则计算哈希:密码转UTF-16LE + salt,再做MD5
        password_utf16le = password.encode('utf-16le')
        computed_hash = hashlib.md5(password_utf16le + salt).digest()

        return computed_hash == stored_hash

    def encode(self, password, salt=None):
        # 若需要生成兼容PWDENCRYPT的哈希可使用此方法,我们主要用验证逻辑
        if salt is None:
            salt = os.urandom(4)  # 生成4字节随机salt
        password_utf16le = password.encode('utf-16le')
        computed_hash = hashlib.md5(password_utf16le + salt).digest()
        
        # 拼接成SQL Server格式的哈希字符串
        return f"0x0100{salt.hex()}{computed_hash.hex()}"

将这个哈希器添加到Django配置的PASSWORD_HASHERS列表中,放在默认哈希器之前:

PASSWORD_HASHERS = [
    'your_app_name.hashers.MSSQLPWDENCRYPTHasher',  # 替换为实际路径
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    # 保留其他默认哈希器...
]

这样迁移过来的用户就能直接使用原密码登录,登录成功后Django会自动用默认的强哈希算法重新加密密码并存入数据库,后续就无需再依赖这个自定义哈希器了。

内容的提问来源于stack exchange,提问作者decibyte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:40:41