发表于: 2019-11-09 00:09:56
1 1190
今天完成的事情:
看了一堆DES的东西记录下,基本是明白了整个过程
一.DES算法
1.DES所需要的参数
data:需要加解密的数据,8字节64bit
key:秘钥,8字节64bit
mode:工作方式,加密还是解密
DES加密的过程:
初始置换IP-->加密过程(迭代)-->IP逆置换-->密文
具体过程如下图所示:
2.初始置换IP
将64位初始明文data按照置换规则变成64密文A,置换规则如下所示,置换完毕后,得到一个新的64位数据B,将B分成两份32位数据,L0和R0,分别指代前32位和后32位
注意:这些数子指的是64位的顺序(2进制),而非数据本身
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
将第1位置换至40位,第二位置换至第8位...,这里指的位数是2进制表示形式
3.加密过程(迭代)
这个过程指的是将初始置换后的数据L0,R0 ,以及秘钥K0经过16层完全相同的运算
16次运算中会产生 L0~L16,R0~R16,K1~K16,期间他们之间的关系是
Ln = Rn-1
Rn = Ln-1 ⊕f(Rn-1,Kn)
⊕表示亦或
Kn是指向第n次迭代时输入的秘钥
整个迭代过程的描述是,原来的右半部分变为左半部分,原来的左半部分和f函数输出的结果组成新的右半部分,从而进行下一步
3.1 函数f
函数f是由4部分组成:秘钥置换 Kn(n0~16)生成,扩展置换,s-盒替换,p-盒替换
3.1.1 秘钥置换
秘钥置换其实就是子秘钥的生成,指的是每次迭代时都需要生成一个新的秘钥
(1) 将初始秘钥的奇偶校验位忽略不计,即每8位的最后一位,8,16,24,32,40,48,56,64 ,参与计算的还剩56位,将其按照置换选择表1(如下所示)进行置换
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
将64位秘钥将至56位秘钥不是说将每个字节的第8位删除,而是通过缩小置换选择表(如上所示)的变换变成56位。
再将这56位分成C0(28)和D0(28)两份
(2)将C0和D0进行循环左移变换(左移位数按轮数确定),变换完毕后生产C1和D1,然后将C1(28)和D1(28)合并,去掉第9、18、22、25、35、38、43、54位,再次通过置换选择表2(如下所示)进行置换,生产K1(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
新生产的C1和D1在经过循环左移变换,生产C2,D2,再次进行置换生产K2
循环左移位数
3.2.扩展置换
通过扩展置换E,数据的右半部分Rn从32位扩展到48位。扩展置换改变了位的次序,重复了某些位。
扩展置换的目的:
a、产生与秘钥相同长度的数据以进行异或运算,R0是32位,子秘钥是48位,所以R0要先进行扩展置换之后与子秘钥进行异或运算;
b、提供更长的结果,使得在替代运算时能够进行压缩
扩展置换E的规则
3.3.s-盒替换
Rn扩展置换之后与子秘钥Kn异或以后的结果作为输入块进行S盒代替运算
功能是把48位数据变为32位数据
代替运算由8个不同的代替盒(S盒)完成。每个S-盒有6位输入,4位输出。
所以48位的输入块被分成8个6位的分组,每一个分组对应一个S-盒代替操作。
经过S-盒代替,形成8个4位分组结果。
注意:每一个S-盒的输入数据是64位,输出数据是4位,但是每个S-盒自身是64位!!,一共8个s-盒,所以返回的数据是32位
每个S-和是4行16列的格式,因为二进制4位是0~15
这一步主要是为了将使Rn,和Ln能以相同的位数进行运算
3.4 P-盒置换
S-盒代替运算,每一盒得到4位,8盒共得到32位输出。这32位输出作为P盒置换的输入块。
P盒置换将每一位输入位映射到输出位。任何一位都不能被映射两次,也不能被略去。
经过P-盒置换的结果与最初64位分组的左半部分异或,然后左右两部分交换,开始下一轮迭代。
P-盒置换表(表示数据的位置)共32位
16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,
2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25
将32位的输入的第16位放在第一位,第七位放在第二位,第二十位放在第三位
4.逆置换
将初始置换经过16次迭代,即16次的加密过程,最终我们得到了L16和R16,将此作为逆置换的参数得到最终密文输出块,逆置换是初始置换的逆运算,
初始置换是想1号位放置40号位上,2号位放置8号位上
逆置换是将40号位放在1号位上,8号位放置2号位上
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的运算过程是:
1.明文进行初始置换IP
2.初始置换后分成左右两部分L0和R0
3.L0和R0在秘钥的控制下进行迭代运算f
4.16轮后左右两部分互换组合后再次进行逆运算
5.得到密文结果
整个加密过程中置换规则是指定的,轮循左移是按轮数制定的,8个s-盒是固定的,按照这一系列运算后得出最终密文
相反如果是解密用这同一套算法即可,加密和解密的区别在于,轮循时使用的秘钥是相反的,
加密: k1~k16 ,左移动
解密: k16~k1 , 右移动
参考:
https://www.jianshu.com/p/b17439bfe194
https://blog.csdn.net/qq_27570955/article/details/52442092
明天计划的事情:
遇到的问题:
1.如下代码
private static String byteArrToHexStr(byte[] arrB) throws Exception {
int iLen = arrB.length;
// 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
StringBuffer sb = new StringBuffer(iLen * 2);
for (int i = 0; i < iLen; i++) {
int intTmp = arrB[i];
// 把负数转换为正数
while (intTmp < 0) {
intTmp = intTmp + 256;
}
// 小于0F的数需要在前面补0
if (intTmp < 16) {
sb.append("0");
}
sb.append(Integer.toString(intTmp, 16));
}
return sb.toString();
}
上述代码中位什么要将 intTemp 的负数转成正数???
2.byte和int之间的关系
byte :-128 ~ 127
int :0~255
将0~255的数转成byte 其范围就是 -128~127
即
(byte) 255 = -1
(byte) 129 = -127
这是强转高位截去的原因导致的 0000 0000 0000 0000 0000 0000 1111 1111 ---->255
强转byte 1111 1111
原码:1111 1111
反码:1000 0000
补码:1000 0001 ---------->-1
byte a = -127
int x = a + 256 --->129
(byte)129 ---> -127
这里是否意味着 byte的负数 可以用int的0~255来保存呢????
收获:
评论