DES加密算法详解
一、分组密码
分组密码(又称块密码),顾名思义就是将明文消息编码后的二进制序列划分成固定的大小的块儿,每块儿分别在密钥的控制下经过相关处理变成等长的二进制序列。
1、分组密码设计原则
为了有效抵抗攻击者对密码体制的攻击,Shannon提出三个基本设计思想——扩散、混乱以及乘积密码。
(1)、扩散
所谓扩散,是指每1bit明文的变化尽可能多地影响到输出密文序列的bit,以便隐藏明文的统计特性,也就是指通过影响密钥的bite使被加密过后的密文与明文关联性极小。例如(明文p,密文c):
无扩散性:p1: 00000001 c1:00000010
有扩散性:p2: 00000010 c2:11010101
显然具有扩散性的密码体制更难对其攻击。
(2)、混乱
所谓混乱,是指在加密变换过程中明文、密钥以及密文之间的关系尽可能地复杂,以防止密码破译者采用统计分析法进行破译攻击。
(3)、乘积密码体制
所谓乘积密码体制,就是以某种方式连续执行两个或多个密码,以使得所得到的最后结果或乘积从密码编码的角度比其任意一个组成密码都更强。
S1和S2是两个密码体制,他们的明文空间和密文空间相同(这类密码体制称为内嵌式密码体制),设S1=(P,P,K1,E1,D1), S2={P,P,K2,E2,D2} ,那么 S1和S2的乘积密码体制 S1*S2定义为 {P,P,K1*K2,E,D} ,密钥形式为{K1,K2),
加密 ek 定义为:
e(k1,k2)=ek2(ek1(x))
解密
d(k1,k2)(y)=dk1(ek2(y))
容易证明
d(k1,k2)(e(k1,k2)(x))=x
2、分组密码模式
分组密码只能加密固定长度的分组明文,但是会出现需要加密的明文长度可能超过分组密码的分组长度的情况,此时就需要对分组密码算法进行迭代,以便将长明文进行加密,迭代的方法就称为分组密码的模式。
(1)、ECB(电子密码本模式)
将明文分组加密后结果直接成为密文分组明文分组与密文分组是一一对应的关系;且每明文分组各自独立地进行加密和解密这种加密攻击者无需破译密码就能操纵明文。

用途:传输短数据
优点:简单,利于计算
缺点:不利于隐藏明文,容易被破译
(2)、CBC(密码分组链接模式)
利用上一组加密得到的密文于待加密的明文块儿进行异或。
加密第一个明文块儿前需要准备一个与待加密明文块儿长度相同进制序列初始化向量IV

用途:传输数据分组,认证
优点:安全性相较与ECB模式较高;适用于传输长段报文
缺点:不利于并行计算;误差传递;未对初始化向量进行加密;
(3)、CFB(密文反馈模式)
对前分组的密文进行加密再与下一组的明文进行异或运算得到下一组的密文以此迭代
同样也需要一个初始化向量IV

用途:传输数据流,认证
优点:隐藏了明文形式;分组加密转化为流模式;
缺点:不利于并行计算;误差传递;只有一个初始化向量;
(4)、OFB(输出反馈模式)

用途:有扰信道上传输数据流(卫星通信)
优点:隐藏了明文形式;分组加密转化为流模式;
缺点:不利于并行计算;误差传递;只有一个初始化向量;
3、分组密码迭代结构
(1)、Feistel网络
Feistel网络结构是一种应用于分组密码的对称结构,被用于很多密码算法,如DES、GOST28147-89等。采用Feistel网络结构的密码算法的加解密过程只有子密钥是逆向的。Feistel密码算法分为非平衡密码算法和广义Feistel密码算法,前者加密明文时L0和R0的长度不同,虽然可以提高安全性但是迭代轮数增加,后者在分组加密时分组长度都要求是64bit或128bit;

(2)、SP网络
代换-置换网络(Substitution Permulation Network),简称SP网络,是有S代换和P置换交替进行多次迭代而形成的变换网络,可在后续DES算法中一步理解。

二、DES加密算法
DES算法基本结构:
加密过程:

1、DES的密钥编排

DES的最初64位密钥通过置换选择表PC-1(如下图)得到有效的56位密钥,也就是对原密钥的一个压缩的过程,仔细观察PC-1表也只有56位(少了8的倍数位),我们将初始密钥的的第57位放在第一位,第49位放在第二位…对照着表得到56位密钥。

得到56位密钥,然后将其分组成C0和D0(28位),再进行循环左移,左移位数随迭代轮数会发生生变化。得到C1和D1再将其合并通过置换选择表PC-2得到48位密钥(置换规则与PC-1表置换相同),然后我们便得到了第一个子密钥k1,以C1和D1作为下一轮的输出以此循环得到16个子密钥。
注:置换选择1不在循环体内

2、DES的加密过程
DES加密一轮迭代过程

a、DES的初始置换和逆初始置换
初始置换(IP)是在第一轮迭代前的进行的,目的是将原明文块的位进行换位。逆初始置换则(IP-1)是在最后一轮进行的。其置换表是固定的。逆初始置换就是初始置换的逆置换。如图:

数据块经置换恢复到原有的位置。例如,经初始置换后,明文块的第1位被置换到第40位的位置,再经过逆初始置换,第40位又回到了第1位。
1)初始置换
8行8列,最右边按2,4,6,8,1,3,5,7次序排列,往左边各列以此为紧临右边一列序号加8。经过初始置换得到新的64位数据,再分成两半,各32位,然后再对这两块数据进行轮迭代。
2)逆初始置换
左边第二列按8,7,6,5,4,3,2,1的次序排列,往右边隔一列序号以8递增。
b、F函数
如图,虚线框内对Ri-1的处理过程就是F函数。F函数分为4个部分,扩展置换(E盒)、密钥加、非线性代换(S盒代换)、线性置换(P盒)。

1)扩展置换

扩展置换的目的是将32位输入扩展为48位输出。其扩展方法为:将原本输入的8行4列的数据扩展为8行6列(如上图),从新扩展的两列来看,将第左边的第一位32移到最下面,从上往下是以序列4递增的。将最右边一列的1移到最上面然后从上往下是以序列4递增的。从行来看,除了第一行和最后一行,其他行的序列都是顺序排列的。
2)代换盒
代换盒又称S盒,功能是非线性代换,也是DES中唯一的非线性部分,经过s盒处理,E盒扩展的48位数据又被压缩回32位。


DES的S盒处理其实就是一个查表运算。在查表前,将输入的48位数据分成8组每组6位然后分组进入8个S盒进行运算。例如第六组数据是:110011,将第一位和最后一位提出来作为行数,剩下的作为列数。然后第六组数据:110011 查找S6表。11(二进制)是行(化为十进制)也就是第3行,1001是列也就是第9列。S6第3行第9列对应的十进制数是14,化为二进制为1110。原本6位的数据被压缩成了4位。

3)线性置换运算
P盒置换就是一个简单的置换运算,将S盒代换得到的32位数据按下图所示列表进行排列。例如,将第1位放在第9位。第2位放在17位。

3、DES加解密C++实现
DES.h
#ifndef DESH
#define DESH
#include <string>
using namespace std;
/*DES.h: declaration of the TDES、TBase64、TBase64DES class. */
/* TDES类说明:该类是DES和3DES算法类 */
class CDES {
public:
CDES();
virtual ~CDES();
static char* HexToStr(string s);
static string StrToHex(char* bytes, int bytelength);
static bool EnCode(); //des加密
static bool DeCode(); //des解密
protected:
typedef bool(*PSubKey)[16][48];
//计算并填充子密钥到SubKey数据中
static void SetSubKey(PSubKey pSubKey, const unsigned char Key[8]);
//DES单元运算
static void DES(unsigned char Out[8], const unsigned char In[8], const PSubKey pSubKey, bool Type);
/* 补足8位数据
* Description: 根据协议对加密前的数据进行填充
* @param nType: 类型:PAD类型
* @param In: 数据串指针
* @param Out: 填充输出串指针
* @param datalen: 数据的长度
* @param padlen: (in,out)输出buffer的长度,填充后的长度
* @return true--成功;false--失败;
*/
static bool RunPad(bool bType, int nType, const unsigned char* In, unsigned datalen, unsigned char* Out, unsigned& padlen);
/* 执行DES算法对文本加解密
* Description : 执行DES算法对文本加解密
* @param bType : 类型:加密ENCRYPT,解密DECRYPT
* @param bMode : 模式:ECB,CBC
* @param In : 待加密串指针
* @param Out : 待输出串指针
* @param datalen : 待加密串的长度,同时Out的缓冲区大小应大于或者等于datalen
* @param Key : 密钥(可为8位,16位,24位)支持3密钥
* @param keylen : 密钥长度,多出24位部分将被自动裁减
* @return true--成功;false--失败;
*/
static bool RunDES(bool bType, bool bMode, int PaddingMode, const unsigned char* IV, const unsigned char* In,
unsigned char* Out, unsigned datalen, const unsigned char* Key, unsigned keylen);
private:
/*static int hexCharToInt(char c);*/
enum {
ENCRYPT = 0, // 加密
DECRYPT, // 解密
};
enum {
ECB = 0, // ECB模式
CBC // CBC模式
};
enum {
PAD_ISO_1 = 0, // ISO_1填充:数据长度不足8比特的倍数,以0x00补足,如果为8比特的倍数,补8个0x00
};
};
#endif
DES.cpp
#include "DES.h"
#include "memory.h"
#include <iostream>
#include<fstream>
using namespace std;
/* initial permutation IP */
const 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
};
/* final permutation IP^-1 */
const char IPR_Table[64] = {
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
};
/* expansion operation matrix */
const char E_Table[48] = {
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
};
/* 32-bit permutation function P used on the output of the S-boxes */
const char P_Table[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
};
/* permuted choice table (key) */
const char 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

本文详细介绍了DES加密算法,包括分组密码的设计原则、模式以及迭代结构。重点讲解了DES的密钥编排和加密过程,其中涉及到初始置换、F函数、S盒等关键步骤。此外,还提供了C++实现DES加密和解密的代码示例,涵盖ECB、CBC模式。
最低0.47元/天 解锁文章
5042

被折叠的 条评论
为什么被折叠?



