📄 cdes.cpp
字号:
作 者: 邹德强
更 新 日 期: 2003.12.19
/*******************************************************************/
bool CDES::RunDes(bool bType,bool bMode,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen)
{
//判断输入合法性
if(!(In && Out && Key && datalen && keylen>=8))
return false;
//只处理8的整数倍,不足长度自己填充
if(datalen & 0x00000007)
return false;
bool m_SubKey[3][16][48]; //秘钥
//构造并生成SubKeys
unsigned char nKey = (keylen>>3)>3 ? 3: (keylen>>3);
for(int i=0;i<nKey;i++)
{
SetSubKey(&m_SubKey[i],&Key[i<<3]);
}
if(bMode == ECB) //ECB模式
{
if(nKey == 1) //单Key
{
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
{
DES(Out,In,&m_SubKey[0],bType);
}
}
else
if(nKey == 2) //3DES 2Key
{
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
{
DES(Out,In,&m_SubKey[0],bType);
DES(Out,Out,&m_SubKey[1],!bType);
DES(Out,Out,&m_SubKey[0],bType);
}
}
else //3DES 3Key
{
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
{
DES(Out,In,&m_SubKey[bType? 2 : 0],bType);
DES(Out,Out,&m_SubKey[1],!bType);
DES(Out,Out,&m_SubKey[bType? 0 : 2],bType);
}
}
}
else //CBC模式
{
char cvec[8] = ""; //扭转向量
char cvin[8] = ""; //中间变量
if(nKey == 1) //单Key
{
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
{
if(bType == CDES::ENCRYPT)
{
for(int j=0;j<8;++j) //将输入与扭转变量异或
{
cvin[j] = In[j] ^ cvec[j];
}
}
else
{
memcpy(cvin,In,8);
}
DES(Out,cvin,&m_SubKey[0],bType);
if(bType == CDES::ENCRYPT)
{
memcpy(cvec,Out,8); //将输出设定为扭转变量
}
else
{
for(int j=0;j<8;++j) //将输出与扭转变量异或
{
Out[j] = Out[j] ^ cvec[j];
}
memcpy(cvec,cvin,8); //将输入设定为扭转变量
}
}
}
else
if(nKey == 2) //3DES CBC 2Key
{
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
{
if(bType == CDES::ENCRYPT)
{
for(int j=0;j<8;++j) //将输入与扭转变量异或
{
cvin[j] = In[j] ^ cvec[j];
}
}
else
{
memcpy(cvin,In,8);
}
DES(Out,cvin,&m_SubKey[0],bType);
DES(Out,Out,&m_SubKey[1],!bType);
DES(Out,Out,&m_SubKey[0],bType);
if(bType == CDES::ENCRYPT)
{
memcpy(cvec,Out,8); //将输出设定为扭转变量
}
else
{
for(int j=0;j<8;++j) //将输出与扭转变量异或
{
Out[j] = Out[j] ^ cvec[j];
}
memcpy(cvec,cvin,8); //将输入设定为扭转变量
}
}
}
else //3DES CBC 3Key
{
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
{
if(bType == CDES::ENCRYPT)
{
for(int j=0;j<8;++j) //将输入与扭转变量异或
{
cvin[j] = In[j] ^ cvec[j];
}
}
else
{
memcpy(cvin,In,8);
}
DES(Out,cvin,&m_SubKey[bType ? 2 : 0],bType);
DES(Out,Out,&m_SubKey[1],!bType);
DES(Out,Out,&m_SubKey[bType ? 0 : 2],bType);
if(bType == CDES::ENCRYPT)
{
memcpy(cvec,Out,8); //将输出设定为扭转变量
}
else
{
for(int j=0;j<8;++j) //将输出与扭转变量异或
{
Out[j] = Out[j] ^ cvec[j];
}
memcpy(cvec,cvin,8); //将输入设定为扭转变量
}
}
}
}
return true;
}
/*******************************************************************/
/*
函 数 名 称: RunPad
功 能 描 述: 根据协议对加密前的数据进行填充
参 数 说 明: bType :类型:PAD类型
In :数据串指针
Out :填充输出串指针
datalen :数据的长度
padlen :(in,out)输出buffer的长度,填充后的长度
返回值 说明: bool :是否填充成功
作 者: 邹德强
修 改 历 史:
更 新 日 期: 2003.12.19
/*******************************************************************/
bool CDES::RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen)
{
int res = (datalen & 0x00000007);
if(padlen< (datalen+8-res))
{
return false;
}
else
{
padlen = (datalen+8-res);
memcpy(Out,In,datalen);
}
if(nType == PAD_ISO_1)
{
memset(Out+datalen,0x00,8-res);
}
else
if(nType == PAD_ISO_2)
{
memset(Out+datalen,0x80,1);
memset(Out+datalen,0x00,7-res);
}
else
if(nType == PAD_PKCS_7)
{
memset(Out+datalen,8-res,8-res);
}
else
{
return false;
}
return true;
}
//计算并填充子密钥到SubKey数据中
void CDES::SetSubKey(PSubKey pSubKey, const char Key[8])
{
bool K[64], *KL=&K[0], *KR=&K[28];
ByteToBit(K, Key, 64);
Transform(K, K, PC1_Table, 56);
for(int i=0; i<16; ++i) {
RotateL(KL, 28, LOOP_Table[i]);
RotateL(KR, 28, LOOP_Table[i]);
Transform((*pSubKey)[i], K, PC2_Table, 48);
}
}
//DES单元运算
void CDES::DES(char Out[8], char In[8], const PSubKey pSubKey, bool Type)
{
bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
ByteToBit(M, In, 64);
Transform(M, M, IP_Table, 64);
if( Type == ENCRYPT )
{
for(int i=0; i<16; ++i)
{
memcpy(tmp, Ri, 32); //Ri[i-1] 保存
F_func(Ri, (*pSubKey)[i]); //Ri[i-1]经过转化和SBox输出为P
Xor(Ri, Li, 32); //Ri[i] = P XOR Li[i-1]
memcpy(Li, tmp, 32); //Li[i] = Ri[i-1]
}
}
else
{
for(int i=15; i>=0; --i)
{
memcpy(tmp, Ri, 32); //Ri[i-1] 保存
F_func(Ri, (*pSubKey)[i]); //Ri[i-1]经过转化和SBox输出为P
Xor(Ri, Li, 32); //Ri[i] = P XOR Li[i-1]
memcpy(Li, tmp, 32); //Li[i] = Ri[i-1]
}
}
RotateL(M,64,32); //Ri与Li换位重组M
Transform(M, M, IPR_Table, 64); //最后结果进行转化
BitToByte(Out, M, 64); //组织成字符
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -