概述
DES(Data Encryption Standard,数据加密标准)是一种历史悠久的对称密钥加密算法,由IBM公司在1970年代设计,并于1977年被美国国家标准局选作联邦资料处理标准。DES使用56位密钥对64位的数据块进行操作,经过16轮迭代的替换、置换和异或运算后,将明文转换成长度相同的密文。
DES加解密过程主要包括以下几个步骤。
1、密钥预处理:原始的56位密钥首先通过PC-1置换进行初步变换,然后分为左右两部分(各28位),并分别循环左移不同数量的位数,最终组合生成16个子密钥。
2、加密过程。
(1)初始置换(IP):对输入的64位明文块执行初始置换。
(2)16轮迭代:每一轮迭代包含以下四个步骤:
a、子密钥选择:根据当前轮数从16个子密钥中选取一个。
b、扩展置换(E盒):对上一轮的结果进行扩展置换,将其扩展至48位。
c、异或操作:将扩展后的结果与当前子密钥进行异或运算。
d、S盒代替与P盒置换:将异或后的结果送入S盒进行非线性替换运算,然后再通过P盒进行线性置换。
(3)最终置换(FP):完成16轮迭代后,对结果执行最终置换得到64位密文。
3、解密过程:解密实际上是对加密过程的逆向操作。同样经历初始置换、16轮迭代(但子密钥的使用顺序是反向的),最后通过最终置换得到明文。
CHP_Des类
为了方便使用des加解密算法,我们封装了CHP_Des类。CHP_Des类提供了初始化、设置Key、加密、解密等四个接口。CHP_Des类的头文件,可参考下面的示例代码。
#pragma once class CHP_Des { public: CHP_Des(); ~CHP_Des(); enum IDesCodecMode { DesCodecMode_Standard, DesCodecMode_Speed, DesCodecMode_IndependentSubKey }; void Init(IDesCodecMode mode = DesCodecMode_Standard); int SetKey(char *pKey); int Encrypt(char *pData, int nDataLen); int Decrypt(char *pData, int nDataLen); private: typedef struct _TDesCodecInfo { int puiSP[8][64]; char pInitialPerm[16][16][8]; char pFinalPerm[16][16][8]; unsigned char pSubKeys[16][8]; IDesCodecMode mode; }TDesCodecInfo; void EncryptOneRound(char *pBlock); void DecryptOneRound(char *pBlock); static unsigned int ByteSwap(unsigned int uiData); static void PermInit(char pPerm[16][16][8], char pIP[64]); static void SpInit(TDesCodecInfo &dci); static void Permute(char* pInBlock, char pPerm[16][16][8], char* pOutBlock); static int Feeding(TDesCodecInfo& dci, unsigned int uiData, unsigned char pSubKey[8]); static void Round(TDesCodecInfo& dci, int nNum, unsigned int* pBlock); private: TDesCodecInfo m_dci; };
在上面的示例代码中,我们声明了一个枚举类型IDesCodecMode,用于表示Des算法的加解密模式。
DesCodecMode_Standard:标准模式。
DesCodecMode_Speed:速度模式,没有初始置换(IP)和最终置换(FP)。
DesCodecMode_IndependentSubKey:独立模式,没有置换,密钥长度为128字节。
下面,我们逐个介绍CHP_Des类导出的公共接口。
Init:初始化函数。参数mode为加解密模式,一般默认为标准模式即可。
SetKey:设置加解密的密钥。参数pKey为密钥,标准模式和速度模式时,密钥长度为8个字节;独立模式时,密钥长度为128个字节。返回值为0表示成功,其他为错误码。
Encrypt:加密数据,函数返回后,pData为加密过的数据。参数pData为要加密的数据,参数nDataLen为要加密的数据的长度。返回值为0表示成功,其他为错误码。
Decrypt:解密数据,函数返回后,pData为解密过的数据。参数pData为要解密的数据,参数nDataLen为要解密的数据的长度。返回值为0表示成功,其他为错误码。