📄 rfc2144.txt
字号:
组织:中国互动出版网(http://www.china-pub.com/)
RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm)
E-mail:ouyang@china-pub.com
译者:王安鹏(anpengwang anpengwang@263.net)
译文发布时间:2001-8-22
版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须
保留本文档的翻译及版权信息。
Network Working Group C. Adams
Request for Comments: 2144 Entrust Technologies
Category: Informational May 1997
CAST-128加密算法
(RFC2144——The CAST-128 Encryption Algorithm )
本备忘录的状态
本备忘录为Internet社区提供信息,但没有定义任何类型的Internet标准。本备忘录的
发布没有限制。
摘要
Internet社区需要一种不受限制的加密算法,这种算法的密码长度应该允许在较大范围
内变动,以便用于各种不同的加密应用程序和协议中提供安全性。
本文档描述了一种已经存在的算法,可以满足这些要求。内容包括:密码和密钥安排算
法(第二节)的描述,置换箱(附录A)以及一组测试向量(附录B)。
目录
1 简介 1
2 算法的描述 2
2.1 循环密钥对 2
2.2 不同的循环 2
2.3 置换箱(Substitution Boxes) 3
2.4 密钥表 3
2.4.1. 掩码子钥与旋转子钥 4
2.5 可变的密钥长度 5
2.6 CAST5对象标识符 5
2.7 讨论 6
3 知识产权的问题 6
4 安全性的问题 6
5 参考 6
6 作者地址 7
7 附录A 置换箱(S-Boxes) 7
8 附录B. 测试向量 13
1 简介
本文档描述了CAST-128加密算法,这是一种类似于DES的置换组合网路
(Substitution-Permutation Network,SPN)加密系统,对于微分密码分析、线性密码分析、
密码相关分析具有较好的抵抗力。这种加密还有其他的几个理想的特点,包括雪崩、严格的
雪崩标准(SAC)、位独立标准(BIC)、没有互补属性也不存在软弱或者半软弱的密钥。因
此对于整个Internet社区——要求密码强壮、容易获取的加密算法——而言,这是一种能够
满足一般应用的很好的选择。
Adams[Adams]详细地讨论了CAST设计过程,对于这种算法的分析也可以在网上找到
(比如,[Web1]或[Web2])。
2 算法的描述
CAST-128属于称为Feistel加密的一类加密算法,因此所有的操作都类似于数据加密标
准(DES)。完整的加密算法分下面四步给出。
输入:明文m1...m64; 密钥 K = k1...k128
输出:密文c1...c64
1)(密钥表)从K计算出16对子钥(Kmi, Kri)(参见2.1到2.4节);
2)(L0,R0) <-- (m1...m64)(把明文分为左右两半,L0=m1…m32,R0=m33…m64);
3)(循环16次)对于i从1到16,按下述方法计算Li和Ri:
Li = Ri-1;
Ri = Li-1 ^ f(Ri-1,Kmi,Kri), 其中f在第2.2节中定义。(f根据i的不同,可以是
Type 1、Type 2或者Type 3)
4)c1...c64 <-- (R16,L16) (交换最终得到的L16和R16并连接在一起构成密文。)
解密算法与上述加密算法一致,只不过循环(因此还有子钥对)是按照相反的顺序从
(R16,L16)计算出(L0,R0)。
可以使用附录B中的测试向量验证该算法的正确性。
2.1 循环密钥对
CAST-128在每次循环中使用以对子钥:32位量Km作为“掩码”,5位量Kr用作“旋
转码”。
2.2 不同的循环
CAST-128使用三种不同的循环函数,如下所示(其中“D”是输入函数f的数据,“Ia”
到“Id”分别表示I中从高到低的4个字节)。注意“+”和“-”是以2**32为模的加减法,
“^”是位异或,“<<<”表示循环左移操作。
Type 1: I = ((Kmi + D) <<< Kri)
f = ((S1[Ia] ^ S2[Ib]) - S3[Ic]) + S4[Id]
Type 2: I = ((Kmi ^ D) <<< Kri)
f = ((S1[Ia] - S2[Ib]) + S3[Ic]) ^ S4[Id]
Type 3: I = ((Kmi - D) <<< Kri)
f = ((S1[Ia] + S2[Ib]) ^ S3[Ic]) - S4[Id]
循环1、4、7、10、13和16 使用f 函数Type 1;
循环2、5、8、11和14 使用f函数Type 2;
循环3、6、9、12和15使用f 函数Type 3。
2.3 置换箱(Substitution Boxes)
CAST-128使用8个置换箱:置换箱(s-box)S1、S2、S3和S4是循环置换箱,S5、S6、
S7和S8是密钥表置换箱。尽管8个置换箱总共需要8K字节的内存,但是要注意在实际加
密/解密过程中只需要4K字节,因为子钥的产生通常在输入数据之前就完成了。
置换箱S1-S8的内容参见附录A。
2.4 密钥表
假设128位的密钥是x0x1x2x3x4x5x6x7x8x9xAxBxCxDxExF,其中x0是最高位的字节,
xF是最低位的字节。
令z0…zF是中间(临时)字节。
令S[i]表示置换箱i,“^”代表异或加。
按照下述公式从密钥x0x1x2x3x4x5x6x7x8x9xAxBxCxDxExF生成子钥:
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
K1 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
K2 = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]
K3 = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]
K4 = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
K5 = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]
K6 = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]
K7 = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]
K8 = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
K9 = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]
K10 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]
K11 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]
K12 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
K13 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]
K14 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]
K15 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]
K16 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]
[剩下的一半与上面给出的一样,从最后生成的x0..xF产生密钥 K17 - K32。]
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
K17 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
K18 = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]
K19 = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]
K20 = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
K21 = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]
K22 = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]
K23 = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]
K24 = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
K25 = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]
K26 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]
K27 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]
K28 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
K29 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]
K30 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]
K31 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]
K32 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]
2.4.1. 掩码子钥与旋转子钥
令Km1, ..., Km16为32位的掩码子钥(每次循环使用一个);
令Kr1, … , Kr16为32位的旋转子钥(每次循环使用一个,只是用最低的5位);
for (i=1; i<=16; i++) { Kmi = Ki; Kri = K16+i; }
2.5 可变的密钥长度
CAST-128加密算法被设计为密码长度是可变的,从40位到128位,每次递增8位(就
是说,密码长度可以是40、48、56、64…112、120、128位)。对于不同的密码长度,分别
采用不同的规范:
1) 密码长度从40到80(含80),按照上述算法操作,但是采用12循环而不是16。
2) 如果密码长度大于80位,采用完整的16次循环。
3) 如果密码长度小于128位,则在最低位补0直到128位(因为CAST-128密钥表假
定输入的密码是128位的。)
尽管CAST-128支持上述12种长度的密码,但在典型的应用中发现40、64、80和128
位是最有用的密码长度。因此,只要支持这四种长度的子集对于大多数应用就足够了。
为了避免在使用不同的密码长度操作时发生混淆,CAST-128被认为与名CAST5是同
义的,这样在后面加上密码长度就不会发生歧义了。这样,比方说使用40位密码的CAST-128
就被表示为CAST5-40;如果明确地使用128位密码,应该使用名称CAST5-128。
2.6 CAST5对象标识符
如果需要在协议中的算法协商中,或者其它需要使用对象标识符的上下文中使用
CAST,可以使用以下定义的OID。
algorithms OBJECT IDENTIFIER ::=
{ iso(1) memberBody(2) usa(840) nt(113533) nsn(7) algorithms(66) }
cast5CBC OBJECT IDENTIFIER ::= { algorithms cast5CBC(10) }
Parameters ::= SEQUENCE {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -