本篇博文将介绍对称密码算法中的DES密码的算法原理与代码实现(Java)
DES算法原理DES加密算法是对称加密算法(加密和解密使用同一个密钥)中的一种,DES也是分组密码,以64位为分组对明文进行加密。
DES算法会对明文进行16轮的迭代加密,具体的算法过程可以看下面这图(来自文末参考博文中的图,做了一些修改)。看一遍有点绕就那笔跟着走一遍。
下面这张图是每次迭代的的一个提取,我们从中可以直接观察到的就是迭代的两个规律:
Li = Ri-1 Ri = Li-1 ^ F(Ri-1, Ki)上一轮的输出作为下一轮加密的输入(也就是迭代的过程)。同样,子密钥也是迭代产生。
在总体概览了一遍后,我们可以将DES算法分为3部分来讲解。从第一张图从右往左,轮子密钥(子密钥)的生成、F函数的实现以及16次迭代的过程。
子密钥的产生如图上的流程图所示,将所给的初始64位密钥(若是密钥不足64位则前面加0补充至64位),经过PC-1置换压缩成56位。然后分成左右28位,表示成C0, D0。C0和D0按照循环左移表来分别循环左移,此处是第一次循环,所以循环左移1次,生成C1和D1。然后C1和D1合并成56位密钥经过PC-2置换压缩成48位的K1。
K2的生成过程:C1和D1分别循环左移1次,然后合并经过PC-2置换压缩成K2。Ki的生成就为Ci-1和Di-1分别循环左移,然后合并经过PC-2置换压缩而成。
PC-1 置换表 PC-2置换表 循环左移表
//PC-1置换表 private int[] PC1={ 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}; //PC-2置换表 private int[] PC2={ 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}; //循环左移次数表 private int[] leftTable = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; F函数的原理F函数的内部还是比较复杂,不过问题不大。我们按照F函数内部执行顺序来可以分为以下几步:
Ri-1做一个E扩展,从32位扩展成48位
Ri-1与Ki异或运算,然后将异或运算的结果经过S盒选择压缩成32位
从S盒出来的32位结果再经过P置换,就得到最终的32位Ri
Ri-1做扩散选择的表如下:
//E扩展 private int[] ETable={ 32,1,2,3,4,5, 4,5,6,7,8,9, 8,9,10,11,12,13, 12,13,14,15,16,17, 16,17,18,19,20,21, 20,21,22,23,24,25, 24,25,26,27,28,29, 28,29,30,31,32,1};从S盒出来的32位结果经过的P表如下:
//P置换 private int[] P={ 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};在这三步中最为机密的就是S盒的选择压缩了。S盒是如何实现选择压缩呢?我们就要知道S的结构了。
S盒的结构
我们可以看出,进入S盒后将Ri-1与Ki异或的值分成8组,每组6位,分别进入S1-S8盒,然后从每个盒中出4位,合并成32位的结果。
若是还想探究6位变成4位是如何的变换的,就需要看下面这点介绍:
我们以进入S!盒为例,假设进入的6位二进制数为101001,我们一般将第一位和最后一位(从左到右)作为行坐标,中间四位作为纵坐标找值。11即3行,0100即4列(从0开始编号),最后选出的值就为4,四位二进制表示则为0100。
16次的迭代加密最初我们需要将初始的明文做一个IP置换,然后分成左右各32位即L0 R0,带入L0、R0去计算L1和R1。
16次迭代的规律为:
Li = Ri-1 Ri = Li-1 ^ F(Ri-1, Ki)最后,L16与R16直接交换赋给L17和R17(L17=R16, R17=L16),然后L17与R17合并后通过IP逆置换生成最终的密文。