PEP 272 – 块加密算法 API v1.0
- 作者:
- A.M. Kuchling <amk at amk.ca>
- 状态:
- 最终
- 类型:
- 信息性
- 创建:
- 2001年9月18日
- 修订历史:
- 2002年4月17日,2002年5月29日
摘要
本文档指定了用于秘密密钥块加密算法(如 DES 或 Rijndael)的标准 API,从而更轻松地在不同算法和实现之间切换。
引言
加密算法以某种依赖于可变密钥的方式转换其输入数据(称为明文),生成密文。如果且仅当知道密钥时,转换才能轻松地反转。密钥是从某个非常大的可能密钥空间中选择的比特序列。加密算法有两类:块密码和流密码。
块密码加密固定大小的多字节输入(通常为 8 或 16 字节长),并且可以在各种反馈模式下运行。此规范中支持的反馈模式为
编号 | 常量 | 描述 |
---|---|---|
1 | MODE_ECB | 电子密码本 |
2 | MODE_CBC | 密码块链接 |
3 | MODE_CFB | 密码反馈 |
5 | MODE_OFB | 输出反馈 |
6 | MODE_CTR | 计数器 |
这些模式应按照 NIST 出版物 SP 800-38A [1] 中的描述进行实现。前三种反馈模式的描述也可以在布鲁斯·施奈尔(Bruce Schneier)的书籍《应用密码学》[2] 中找到。
(数值 4 保留给 MODE_PGP,这是 RFC 2440:“OpenPGP 消息格式”中描述的 CFB 的变体。这种模式被认为不那么重要,因此不值得要求所有块加密密码都支持它,尽管支持它是一个不错的额外功能。)
从严格的形式意义上讲,流密码逐位加密数据;实际上,流密码以逐字符为基础工作。此 PEP 仅旨在为块密码指定接口,尽管流密码可以通过将“block_size”固定为 1 来支持此处描述的接口。反馈模式对流密码也没有意义,因此唯一合理的反馈模式将是 ECB 模式。
规范
加密模块可以在此 PEP 中描述的功能、方法和属性之外添加其他功能、方法和属性,但要声明模块符合此 PEP,则必须存在 PEP 中描述的所有功能。
秘密密钥加密模块应定义一个函数
new(key, mode, [IV], **kwargs)
返回一个加密对象,使用字符串“key”中包含的密钥,并使用反馈模式“mode”,该模式必须是上述表格中的一个常量。
如果“mode”为 MODE_CBC 或 MODE_CFB,则必须提供“IV”,并且它必须是与块大小相同的长度的字符串。不提供“IV”的值将导致引发ValueError
异常。
根据算法的不同,模块可能支持此函数的其他关键字参数。此 PEP 指定了一些关键字参数,并且模块可以自由添加其他关键字参数。如果未为给定关键字提供值,则应使用安全默认值。例如,如果某个算法在 1 到 16 之间具有可选的轮数,并且 1 轮加密不安全,而 8 轮加密被认为是安全的,则“rounds”的默认值应为 8 或更大。(模块实现者也可以选择一个非常慢但安全的值,例如本例中的 16。此决定留给实现者。)
下表列出了此 PEP 定义的关键字参数
关键字 | 含义 |
---|---|
counter | 返回计数器块的可调用对象(请参见下文;仅限 CTR 模式) |
rounds | 要使用的加密轮数 |
segment_size | 数据和密文段的大小,以位为单位(请参见下文;仅限 CFB 模式) |
计数器反馈模式需要一系列输入块,称为计数器,用于生成输出。当“mode”为 MODE_CTR 时,必须提供“counter”关键字参数,并且其值必须是可调用对象,例如函数或方法。对该可调用对象的连续调用必须返回一系列长度为“block_size”且永不重复的字符串。(NIST 出版物的附录 B 提供了一种生成此类序列的方法,但这超出了本 PEP 的范围。)
CFB 模式对长度为“segment_size”位的明文和密文段进行操作。因此,在使用此模式时,输入和输出字符串的长度必须是“segment_size”位的倍数。“segment_size”必须是 1 到 block_size*8(含)之间的整数。(因子 8 来自“block_size”以字节为单位而不是以位为单位)。此参数的默认值应为 block_size*8。为了简单起见,实现者可以将“segment_size”限制为 8 的倍数,但为了通用性,鼓励他们支持任意值。
秘密密钥加密模块应定义两个变量
- block_size
整数值;此模块加密的块的大小,以字节为单位。对于所有反馈模式,传递给 encrypt() 和 decrypt() 的字符串的长度必须是块大小的倍数。
- key_size
整数值;此模块所需的密钥的大小,以字节为单位。如果 key_size 为 None,则算法接受可变长度密钥。这可能意味着模块接受任何随机长度的密钥,或者有几个不同的可能长度,例如 16、24 或 32 字节。您不能将长度为 0 的密钥(即空字符串“”)作为可变长度密钥传递。
密码对象应具有两个属性
- block_size
整数值,等于此对象加密的块的大小。对于块大小可变的算法,此值等于为此对象选择的块大小。
- IV
包含将用于启动密码反馈模式的初始值;它始终是一个正好一个块长度的字符串。加密或解密字符串后,此值将更新以反映修改后的反馈文本。它是只读的,不能分配新值。
密码对象需要以下方法
- decrypt(string)
解密“string”,使用对象中与密钥相关的数据以及适当的反馈模式。字符串的长度必须是算法块大小的精确倍数,或者在 CFB 模式下,是段大小的精确倍数。返回包含明文的字符串。
- encrypt(string)
加密非空字符串,使用对象中与密钥相关的数据以及适当的反馈模式。字符串的长度必须是算法块大小的精确倍数,或者在 CFB 模式下,是段大小的精确倍数。返回包含密文的字符串。
这是一个示例,使用名为“DES”的模块
>>> import DES
>>> obj = DES.new('abcdefgh', DES.MODE_ECB)
>>> plaintext = "Guido van Rossum is a space alien."
>>> len(plaintext)
34
>>> obj.encrypt(plaintext)
Traceback (innermost last):
File "<stdin>", line 1, in ?
ValueError: Strings for DES must be a multiple of 8 in length
>>> ciphertext = obj.encrypt(plain+'XXXXXX') # Add padding
>>> ciphertext
'\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006'
>>> obj.decrypt(ciphertext)
'Guido van Rossum is a space alien.XXXXXX'
参考文献
更改
2002-04:删除了对流密码的引用;重新命名 PEP;在反馈模式常量前添加了MODE_
;删除了 PGP 反馈模式;添加了 CTR 和 OFB 反馈模式;阐明了数字以字节为单位还是以位为单位。
2002-09:使用“可变长度密钥”代替“任意长度”阐明了密钥长度的讨论。
致谢
感谢 python-crypto 列表的读者对本 PEP 的评论。
版权
本文档已进入公有领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0272.rst
上次修改时间:2023年9月9日 17:39:29 GMT