PEP 247 – 加密哈希函数的 API
- 作者:
- A.M. Kuchling <amk at amk.ca>
- 状态:
- 最终版
- 类型:
- 信息性
- 创建日期:
- 2001年3月23日
- 修订历史:
- 2001年9月20日
摘要
目前有几个不同的模块实现了诸如 MD5 或 SHA 等加密哈希算法。本文档指定了此类算法的标准 API,以便于在不同实现之间切换。
规范
所有哈希模块都应提供相同的接口。可以添加其他方法或变量,但本文档中描述的方法应始终存在。
哈希函数模块定义一个函数
new([string]) (无密钥 哈希)
new([key] , [string]) (带密钥 哈希)
创建一个新的哈希对象并返回它。第一种形式用于无密钥哈希,例如 MD5 或 SHA。对于带密钥的哈希(例如 HMAC),key 是一个必需的参数,包含一个字符串,用于指定要使用的密钥。在这两种情况下,如果提供了可选的 string 参数,则会立即将其哈希到对象的初始状态,就像调用了obj.update(string)
一样。创建哈希对象后,可以使用其
update()
方法将任意字符串馈送到对象中,并且可以通过调用对象的digest()
方法随时获取哈希值。可以为此函数添加任意其他关键字参数,但如果没有提供,则应使用合理的默认值。例如,可以为支持可变轮数和几种不同输出大小的哈希函数添加
rounds
和digest_size
关键字,并且它们应默认为被认为是安全的的值。
哈希函数模块定义一个变量
digest_size
一个整数值;由该模块创建的哈希对象生成的摘要的大小,以字节为单位。您还可以通过创建一个示例对象并访问其digest_size
属性来获取此值,但从模块中获取此值会很方便。具有可变输出大小的哈希将此变量设置为None
。
哈希对象需要一个属性
digest_size
此属性与模块级digest_size
变量相同,用于测量哈希对象生成的摘要的大小,以字节为单位。如果哈希具有可变输出大小,则必须在创建哈希对象时选择此输出大小,并且此属性必须包含所选大小。因此,None
不是此属性的合法值。
哈希对象需要以下方法
copy()
返回此哈希对象的单独副本。对此副本的更新不会影响原始对象。
digest()
将此哈希对象的值作为包含 8 位数据的字符串返回。此函数不会以任何方式更改对象;在调用此函数后,您可以继续更新对象。
hexdigest()
将此哈希对象的值作为包含十六进制数字的字符串返回。对于数字a
到f
,应使用小写字母。与.digest()
方法一样,此方法不得更改对象。
update(string)
将 string 哈希到哈希对象的当前状态中。在哈希对象的整个生命周期中,可以多次调用update()
。
哈希模块可以定义其他模块级函数或对象方法,并且仍然符合此规范。
这是一个示例,使用名为 MD5
的模块
>>> from Crypto.Hash import MD5
>>> m = MD5.new()
>>> m.digest_size
16
>>> m.update('abc')
>>> m.digest()
'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'
>>> m.hexdigest()
'900150983cd24fb0d6963f7d28e17f72'
>>> MD5.new('abc').digest()
'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'
原理
摘要大小以字节为单位测量,而不是以位为单位,即使哈希算法大小通常以位为单位引用;例如,MD5 是一种 128 位算法,而不是 16 字节算法。这是因为,在我查看的示例代码中,通常需要以字节为单位的长度(例如,在文件中向前或向后查找;计算输出字符串的长度),而很少使用以位为单位的长度。因此,负担将落在少数实际需要以位为单位的长度的人身上,他们将不得不将 digest_size
乘以 8。
有人建议将 update()
方法更好地命名为 append()
。但是,该方法实际上是在导致哈希对象的当前状态更新,并且 Python 附带的 md5 和 sha 模块已经使用了 update()
,因此将名称保留为 update()
似乎最简单。
带密钥哈希的构造函数参数顺序是一个棘手的问题。不清楚 key 应该放在第一位还是第二位。它是一个必需的参数,通常的做法是将必需的参数放在前面,但这同时也意味着 string 参数从第一位置移到第二位置。可能会混淆并向带密钥的哈希传递单个参数,以为您正在向无密钥的哈希传递初始字符串,但这似乎不值得为了避免此潜在错误而使带密钥的哈希的接口变得更加模糊。
变更
2001年9月17日:将 clear()
重命名为 reset()
;向对象添加了 digest_size
属性;添加了 .hexdigest()
方法。
2001年9月20日:完全删除了 reset()
方法。
2001年9月28日:对于可变大小的哈希,将 digest_size
设置为 None
。
致谢
感谢 Aahz、Andrew Archibald、Rich Salz、Itamar Shtull-Trauring 以及 python-crypto 列表的读者对本 PEP 的评论。
版权
本文档已进入公有领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0247.rst
上次修改时间:2023年9月9日 17:39:29 GMT