一个有具体流程的:http://blog.chinaunix.net/uid-29106641-id-4032988.html
pdf版的:http://www.ieccr.net/xdmmx/shijianjiaoxuedoc/1-2.pdf
目前困扰我的问题有:如果密文的长度大于或者少于64比特会怎么办。
解决方案:分块处理,有ECB,CBC,等具体请戳:https://www.wikiwand.com/zh/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F
https://crypto.stackexchange.com/questions/1064/how-can-i-encrypt-more-than-64-bit-with-the-data-encryption-standard
按照流程图:
DES算法的原理:
1.
明确会有data(用于加密的数据),key(密钥),mode(加密或者解密)
2.
首先将data(二进制的形式,我们可以先造一个适合的64位的二进制数组)根据IP表的变换而变换。
//拟造的data
static bool data[64] = {
1,0,1,0,0,0,0,0,
1,1,1,0,1,1,1,1,
0,0,1,0,1,0,0,1,
0,1,0,0,1,0,1,0,
0,1,1,1,0,1,1,1,
0,0,0,1,1,1,1,0,
0,1,0,0,0,1,1,0,
0,0,1,0,1,0,1,0
};
//IP表
const static char IP_Table[64] = {
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
};
意义为:IP表中的58指的是data表的第58个数(从1开始算的,不是数组的从0开始算)在经过IP变换后要放置在第0位,49放在第1位。
3.
将置换过后的64位数据分为L0和R0两部分。L0为前32位,R0为后32位。
4.
下面的16轮相同运算是这个里面最麻烦的一个,也是一个重点。分几点来讲。
4.1.
密钥的生成。也就是Key,为了增加破解难度,每一层使用的Key都是基于上一层Key经过转换而得到的。具体的转换方法是:
DES算法由64位密钥产生16轮的48位子密钥。在每一轮的迭代过程中,使用不同的子秘钥。
a、把密钥的奇偶校验位忽略不参与计算,即每个字节的第8位,将64位密钥降至56位,然后根据选择置换PC-1将这56位分成两块Key_L0(28位)和Key_R0(28位);
b、将Key_L0 and Key_R0进行循环左移变化(注:每轮循环左移的位数由轮数决定),变换后生成Key_Moved_L0和Key_Moved_R0,然后Key_Moved_L0和Key_Moved_R0合并,并通过选择置换PC-2生成子密钥K1(48位);
c、Key_L1和Key_R1在次经过循环左移变换,生成Key_Moved_L1和Key_Moved_R1,然后Key_Moved_L1和Key_Moved_R1合并,通过选择置换PC-2生成密钥K2(48位);
d、以此类推,得到K16(48位)。但是最后一轮的左右两部分不交换,而是直接合并在一起R16L16,作为逆置换的输入块。其中循环左移的位数一共是循环左移16次,其中第一次、第二次、第九次、第十六次是循环左移一位,其他都是左移两位。
//PC1选位表(密钥生成置换表1)
const static int PC1_Table[56] = {
57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4
};
//PC2选位表(密钥生成置换表2)
const static int PC2_Table[48] = {
14,17,11,24,1,5,
3,28,15,6,21,10,
23,19,12,4,26,8,
16,7,27,20,13,2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32
};
//左移位数表
const static int LOOP_Table[16] = {
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};