Python2迁移Python3时hashlib哈希计算写法正确性咨询
问题背景
提示:所有变量均为字符串类型,使用hashlib库。
常量与依赖定义:
from hashlib import sha256, md5 S2_SRP_MAGIC1 = "[!~esTo0}" S2_SRP_MAGIC2 = "taquzaph_?98phab&junaj=z=kuChusu" S2_SALT2 = "p^^^&bjRlXi4B=A1y.@Vz)" password = "asd"
以下代码在Python 2环境可正常运行:
p = sha256(md5(md5(password + S2_SALT2 + S2_SRP_MAGIC1) + S2_SRP_MAGIC2))
移植到Python 3运行时抛出错误:
TypeError: Unicode-objects must be encoded before hashing
修改后代码消除了报错,但SRP认证始终失败,修改后的代码如下:
p = sha256((md5((md5(password.encode()).hexdigest() + S2_SALT2 + S2_SRP_MAGIC1).encode()).hexdigest() + S2_SRP_MAGIC2).encode()).hexdigest()
解答
你的修改是完全错误的,和Python 2环境的计算逻辑不一致,这就是SRP认证失败的直接原因。
核心错误点:Python 2中的str类型本质是字节串,md5()传入字节串后,直接返回二进制格式的哈希摘要字节串参与后续拼接、二次哈希。你修改时在每一层md5计算后都调用了.hexdigest(),把原本参与运算的二进制摘要替换成了十六进制文本字符串,整个哈希流程的输入和Python 2版本完全不同,最终算出的哈希值必然不匹配。
正确的Python 3适配写法
所有参与哈希的字符串在传入哈希函数前统一编码为字节串(编码要和原Python 2环境保持一致,通常默认用utf-8即可),哈希返回的结果直接取二进制.digest()参与后续拼接运算,仅在最后需要输出结果时转十六进制:
# 编码和原Python2运行环境保持一致,常用utf-8,特殊场景替换为gbk/latin-1等对应编码即可 encode_type = "utf-8" p = sha256( md5( md5( (password + S2_SALT2 + S2_SRP_MAGIC1).encode(encode_type) ).digest() + S2_SRP_MAGIC2.encode(encode_type) ).digest() ).hexdigest()
内容的提问来源于stack exchange,提问作者SuperBjorn
相关产品推荐
相关产品推荐

