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定义的关键字参数
| 关键字 | 含义 |
|---|---|
| 计数器 | 可调用对象,返回计数器块(见下文;仅限CTR模式) |
| 回合数 | 要使用的加密回合数 |
| 分段大小 | 数据和密文段的大小,以位为单位测量(见下文;仅限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