?? des.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 + -