DES加密实现(翻译自书籍《Wiley.Implementing.SSL.TLS.Using.Cryptography.and.PKI》)
Posted qq_28674045
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DES加密实现(翻译自书籍《Wiley.Implementing.SSL.TLS.Using.Cryptography.and.PKI》)相关的知识,希望对你有一定的参考价值。
理解BlockCipher加密算法
- 凯撒大帝被认为是最古老的对称加密算法。所谓的凯撒加密法(你也许可以从报纸上找到一个作为消遣来玩),它随机的给每一个字母分配一个数字。在这个简单的算法当中,字母到数字的映射就是key。现代加密算法比凯撒算法肯定复杂的多,以便抵御来自计算机的攻击。尽管基本原理是一样,替换一个字母或其它什么东西为另外一个字母或其它什么东西,后续都对替换后的东西进行处理,在几个世纪以来,更多的混淆和扩散(confusion and diffusion)要素被加入,从而创建了现代加密算法。一个很重要的技术就是同时操作一组字符,而不是一个。现在用的最多的对称加密算法类别就是块加密算法,它对固定数目的字节进行操作,而不是一个字符。
- 在这一部分我们来考察3种最流行的块加密算法,也是我们在工作中最可能碰到的现代加密算法。这些算法也许会在未来几十年还有意义,要修改加密标准,那个过程是非常非常慢的;需要密码专家进行大量的研究和分析。
实现DES加密算法
- DES是Data Encryption Standard(数据加密标准)的简称,它是1974年,在NSA的要求下,由IBM实现和提出的;它也是第一个可以公开获取的针对计算机的加密算法。尽管在后文你看可以看到,DES不再认为是足够安全的,但是它还在被广泛地使用着。并且它也是学习对称加密算法的好入口。DES中的绝大多数概念都会在其它加密算法中出现。
- DES将输入分成8字节的块,然后使用一个8字节的key来混淆它们。这个混淆的过程有一系列的固定置换(将第34位和28位互换,28位和17位互换等等)、轮换以及XORs。尽管DES的核心(也就是DES为什么是安全的)是因为S boxes的操作,经过它输入的每6个bit,都会固定地4bit的输出;但是这个过程是不可逆的(除非有key)。
- 和任何现代对称加密算法一样,DES也非常依赖于XOR操作。【异或操作介绍略】
- 异或一个非常有趣的属性就是它是可逆的,比如:
- 在实现DES的时候,我们一般操作的是字节数组,以便充分利用硬件对整数操作的优势。传统上,DES是使用大端来描述的,但是x86等架构都是小端的;为了充分利用硬件性能,我们需要对规范中的一些部分进行反转,不过在这里,我们不需要这么做
- 作为一个替代方案,我们操作byte数组。因为我们需要操作位,比如:得到64bit中的第39个bit的值;因此我们需要一些宏的支持,从而可以方便的对字节数组进行bit查找和操作。bit操作的宏如下所示:
#define GET_BIT( array, bit ) \\
( array[( int ) ( bit /8 ) ] & ( 0x80 >> (bit % 8 ) ) )
#define SET_BIT( array, bit ) \\
( array[( int ) ( bit /8 ) ] |= ( 0x80 >> (bit % 8 ) ) )
#define CLEAR_BIT( array, bit ) \\
( array[( int ) ( bit /8 ) ] &= ~( 0x80>> ( bit % 8 ) ) )
- 因为这个例子是对字节数组求异或的,所以需要一个方法来支持异或操作。
static void xor( unsignedchar *target, constunsigned char *src, int len )
{
while ( len-- )
{
*target++^= *src++;
}
}
- 最后我们还需要一个置换(permute)函数,这个函数根据 permute_table数组对输入进行bit置换,比如:输入的第57bit放到输出的第14bit。正如你下面会看到的,这个函数是DES算法调用最频繁的地方;它被调用了10多次(使用不同的置换表permute_table)
/**
* Implement the initialand final permutation functions. permute_table
* and target must haveexactly len and len * 8 number of entries,
* respectively, but srccan be shorter (expansion function depends on this).
* NOTE: this assumesthat the permutation tables are defined as one-based
* rather than 0-basedarrays, since they’re given that way in the
* specification.
*/
static void permute( unsignedchar target[],
const unsigned char src[],
const int permute_table[],
int len )
{
int i;
for ( i = 0; i <len * 8; i++ )
{
if ( GET_BIT( src,( permute_table[ i ]- 1 ) ) )
{
SET_BIT(target, i );
}
else
{
CLEAR_BIT( target, i );
}
}
}
DES初始置换
- DES规范中要求对输入进行一个初始置换。这个置换的目的是什么还不是很清楚,因为它没有任何加密的效果(置换后的安全效果和置换前是一样的)。加入这个置换的目的,也许是为了对某些硬件类型进行优化。尽管如此,如果你不进行这个操作,你的DES加密结果将会是错误的,也不能够和其它实现进行交互。
- 在规范中,对这个置换的描述使用术语:input bits和output bits。它的操作如下:将input最后一个字节的第2个bit拷贝到output第一个字节的第一个bit;然后将input倒数第二个字节的第2个bit拷贝到output第一个字节的第2个bit等等。因此,output的第一个字节是由input左右字节中的第2个bit组成的(反向的)。output的第2个字节是input每个字节的第4个bit组成的(也是反向的)。output的第3个字节是input每个字节的第6个bit组成的,output的第4个字节由input每个字节的第8个bit组成,output的第5个字节由input每个字节的第1个字节组成,等等。
- 故给定8个字节作为输入,操作的结果如下:
- 实现这个置换可以使用前面的置换(permute)函数,其中permute_table如下:(注意:DES认为字节序是大端的)
比如:第一个字节是由原字节数组中,每个字节的第2个bit组成。
原字节数组位数的大小,从左到有为:1到64,上图字节数组中标识为1的为58,2为50等等
static const int ip_table[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7 };
- 在输入被置换之后, 它又被用key进行了16轮的操作组合,每一轮做的操作如下:
- 扩展输入的第32到第64位到48bits(下面会进行描述)
- 将扩展后的右边部分和key做XOR
- 使用上面的输出,查询8个s-box表,并使用这些内容来覆盖输入
- 根据特定的p表来对输出进行置换
- 将输出和输入的左边部分(1~32)做XOR,然后对左右部分交换;在下一轮,相同的操作被执行,但是左右部分被调换了
- 最终,前后部分做最后一次交换,然后对输出做初始置换的反操作,也就抵消了初始置换。
/**
* This just invertsip_table.
*/
static const int fp_table[] = { 40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25 }
上面是最后使用的置换表。
DES Key Schedule
- 在算法描述的第2步中,“将扩展后的右边部分和key做XOR”。如果我们看了图,就会发现,图中的key,分别标记为K1,K2、K3…K15、K16. 也就是说有16个不同的48bit的key,他们都是通过原始的64bit数据加密标准DES详细过程总结代码(自运行可实现)