流密码: 传输过程当中数据流的每一位都被加密, 密钥流须要提早经过某种安全的方式提供给双方. 而处于实用的缘由, 后来咱们能够经过共享的短密钥与约定的算法来在发送方和接收方产生相同的密钥流来进行加密, 这样确定是一种不错的方法.web
分组密码: 将明文的一个分组做为加密的对象, 与流密码相比就是每次加密的单位大小不一样. 典型的分组大小是64位, 128位, 256位等.算法
扩散: 使明文的统计特征消散在密文中编程
混淆: 使密文的统计特征与密钥的取值之间的关系更加模糊数组
Feistel将一个分组分为等长的两部分(L0和R0), 通过一轮的迭代分组会变为L1和R1, 经典的方法是进行16轮迭代, 因此也就是生成L16和R16. 解密就是这个迭代的逆过程.安全
下面的方程解释迭代的过程svg
其中 是第i轮的密钥, F是一种对输入的处理方法, 这个处理方法相对比较复杂, 在本文的后面会展开来讲函数
参考了Apollon_krj的博客, 很好地解释了子秘钥产生的过程atom
首先咱们给出两张流程图, 和以前的Feistle加密同样都是分组交替加密, 可是DES又引入了其余的机制, 接下来咱们将一部分一部分地展开来说加密
咱们先从明文被加工的过程讲起, 这个过程就像经历一条生产流水线同样spa
那么你可能会问了, 初始置换如何进行的? 函数F内部是怎么样进行处理的? 末置换是怎么样进行处理的? 不要着急, 咱们接下来就会一个一个地解答你的问题
好比咱们使用以下的矩阵来将64位的明文进行初始置换和末置换
咱们发现第一行第一列为40, 也就是说分组A的第1位是分组P的第40位, 咱们还发现第一行第二列为8, 也就是说分组A的第2位是分组P的第8位, 以此类推
F函数比较复杂, 可是咱们仍是来一步一步地来分解, 首先给出其流程图
咱们发现, 对于R(i-1), 他经历了以下几个过程
看到这么复杂的过程是否是有点晕, 不慌, 咱们仍是一步一步分解
经过如图的扩展E置换的矩阵, 通过相似于初始置换的映射方法进行扩展, 将32位的串A扩展为48位的串B
首先因为DES是16轮循环,因此须要由64bit的随机密钥Key生成16个子密钥Ki(i从0~15),Key共64bit,可是其每一个字节的最后一位都用不到(即第八、1六、2四、3二、40、4八、5六、64位共8位),因此先经过初始置换将64bit的密钥转换为56bit。而转换是根据密钥转换表(编程时一系列表均用数组来存储)来操做的,以下所示:
该表共有56个元素(能够看到不包含八、1六、2四、3二、40、4八、5六、64),表明了转换后的56bit的位置(即output的下标)。
好比:第1位(下标为0,位置为1)的值为57, 则获取原来的第57位的bit值(0或1),做为置换后的第1位的bit值。依次类推
通过置换的key变为56bit,该56bit分为左右两半部分:left_key和right_key,各28bit,而后左右两部分分别循环左移必定位数n。n的大小根据这是第几轮来决定,以下表所示(最多循环左移两位,最少一位):
通过移位的左右两部分合并为56bit,而后通过压缩置换将56bit压缩为48bit,则产生一个子密钥Ki,通过16轮循环产生16个子密钥(对应DES结构图)。而压缩置换的压缩表以下:
S盒的做用是什么? 那就是将48位串压缩为32位串.
其原理图如图
能够看到一个S盒里有8个S-BOX, 一个盒子对应着一个特殊的矩阵, 好比以下给出了8个盒子各自的矩阵
对于其中的一个矩阵, 经过以下方式压缩
咱们能够看到, 每一个6位串的第1位和第6位合起来决定选择矩阵中的第几行, 中间四位决定选择第几列, 这样就保证了以前的扩展位在以后的压缩中会被舍弃而不会影响到数据的正确性.
关于S-box有如下几点须要关注
P盒的做用是什么? 那就是将32位串映射为32位串.
这个映射的过程经过以下的矩阵来实现