Python hashlib.scrypt方法中maxmem参数的正确取值计算方式
Python hashlib.scrypt的maxmem参数正确计算方式
问题背景
我尝试使用Python的hashlib.scrypt对密码进行哈希处理,按照OWASP的推荐配置:CPU/内存成本参数n最小值为2^17,块大小r最小值为8,并行化参数p为1。参考资料推荐用公式128 * n * r作为maxmem的取值,但使用该公式时触发以下报错:
from hashlib import scrypt scrypt(b'password', salt=b'775186574b308535c9f0c1bedec71374', n=(2 ** 17), r=8, p=1, maxmem=(128 * (2 ** 17) * 8))
报错信息:
ValueError: [digital envelope routines: EVP_PBE_scrypt] memory limit exceeded
通过试错发现使用128 * n * r + (2 ** 10 + 2 ** 11)可以解决该错误,想了解maxmem参数的正确计算方式。
解答
核心原因
maxmem参数需要覆盖scrypt算法核心计算内存+底层额外临时内存开销。资料里的128 * n * r只是算法核心逻辑所需的理论内存值,但Python的scrypt依赖OpenSSL底层实现,运行时还会用到额外的临时缓冲区,仅用理论值会因内存预留不足触发超限错误。
正确计算方式
- 最小安全取值:
maxmem需至少大于等于128 * n * r + 3072(即128*n*r + 2^10 + 2^11,和你试出的取值一致),3072字节是OpenSSL底层所需的额外缓冲区大小。 - 更省心的方案:无需手动指定
maxmem参数,Python的hashlib.scrypt会自动计算一个足够覆盖额外开销的默认值,通常是理论值的1.5倍以上,能避免手动计算的误差。 - 高配置场景:如果后续调整
n、r参数,可在128 * n * r的基础上额外预留5%~10%的内存,确保稳定运行。
验证说明
你试出的公式刚好补足了OpenSSL所需的额外内存,所以能解决报错。如果需要手动指定,直接套用128 * n * r + 3072即可;追求简便的话,直接省略maxmem参数依赖默认值是更稳妥的选择。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

