如何修复Python hashlib中scrypt的无效参数组合错误
报错根因
Python 3.7版本hashlib.scrypt()未显式指定maxmem参数时,会采用默认32MB的内存限制阈值。
scrypt算法运行所需的基础内存计算公式为 128 * n * r * p(单位:字节),你当前使用的n=16384、r=16、p=1参数代入后,基础内存占用为33554432字节(即32MB),叠加Python运行时的少量管理开销后,实际内存需求超过默认32MB的限制,因此触发参数无效报错。
你当前选用的n/r/p参数本身完全符合RFC 7914规范,不存在参数取值违规问题。
maxmem参数规则说明
- 计量单位为字节,作用是限制scrypt运行时可申请的最大内存,避免异常参数导致程序占满系统内存
- 取值为0时,Python会自动根据传入的n/r/p参数计算所需内存,放开对应限制,无需手动计算内存大小
- 手动传值时,需要保证传入值大于等于scrypt实际运行所需的内存总量,否则就会抛出你遇到的ValueError
修复方案
选择以下任意一种修改方式即可解决问题:
- 显式传入留足冗余的maxmem值,适配当前参数的内存需求,修改后的代码如下:
from os import urandom from hashlib import scrypt def aes_encrypt(msg, passwordStr): kdfSalt = urandom(16) # 16 bytes == 128 bits # 传入64MB内存限制,足够覆盖当前参数的运行开销 hashedKey = scrypt(passwordStr.encode(),salt=kdfSalt,n=16384,r=16,p=1, dklen=64, maxmem=64*1024*1024)
- 直接设置maxmem为0,让Python自动适配内存阈值,无需手动计算大小:
hashedKey = scrypt(passwordStr.encode(),salt=kdfSalt,n=16384,r=16,p=1, dklen=64, maxmem=0)
额外参数校验规则
scrypt对p参数的硬约束为 p ≤ (2^32 - 1) * 32 / (128 * r),在你当前r=16的配置下,p最大可取值为1048575,你设置p=1完全符合规范,无需调整n/r/p的取值。
内容的提问来源于stack exchange,提问作者the_endian
相关产品推荐
相关产品推荐

