作者:finallyliuyu 出处:博客园
声明:此篇博文代码来自于邹德强先生。由于目前找到的版本是残缺版,所以我又进行了补全。读一份好代码,可以领略到作者的编程风格和语言驾驭能力,同时又能从其中汲取养分。现将我所修改后的DES加密解密代码全部张贴出来,有需要的也可以在上面继续改动
comon.h
#ifndef _COMMON_H
#define _COMMON_H
typedef bool ( * PSubKey)[ 16 ][ 48 ];
#endif
#define _COMMON_H
typedef bool ( * PSubKey)[ 16 ][ 48 ];
#endif
myDES.h
#ifndef _myDES_H
#define _myDES_H
#include " common.h "
#include < stdio.h >
class myDES
{
public :
myDES();
~ myDES();
void ByteToBit( bool * Out, const char * In, int bits);
void BitToByte( char * Out, const bool * In, int bits);
void RotateL( bool * In, int len, int loop);
void RotateR( bool * In, int len, int loop);
void Xor( bool * InA, const bool * InB, int len);
void Transform( bool * Out, bool * In, const char * Table, int len);
void S_func( bool Out[ 32 ], const bool In[ 48 ]);
void F_func( bool In[ 32 ], const bool Ki[ 48 ]);
bool RunDes( bool bType, char * In, char * Out,unsigned datalen, const char * Key, const unsigned char keylen);
bool RunPad( int nType, const char * In,unsigned datalen, char * Out,unsigned & padlen);
void SetSubKey(PSubKey pSubKey, const char Key[ 8 ]);
void DES( char Out[ 8 ], char In[ 8 ], const PSubKey pSubKey, bool nType);
bool myRunDES( bool bType, char * In, char * Out,unsigned datalen, const char * Key, const unsigned char keylen);
};
#endif
#define _myDES_H
#include " common.h "
#include < stdio.h >
class myDES
{
public :
myDES();
~ myDES();
void ByteToBit( bool * Out, const char * In, int bits);
void BitToByte( char * Out, const bool * In, int bits);
void RotateL( bool * In, int len, int loop);
void RotateR( bool * In, int len, int loop);
void Xor( bool * InA, const bool * InB, int len);
void Transform( bool * Out, bool * In, const char * Table, int len);
void S_func( bool Out[ 32 ], const bool In[ 48 ]);
void F_func( bool In[ 32 ], const bool Ki[ 48 ]);
bool RunDes( bool bType, char * In, char * Out,unsigned datalen, const char * Key, const unsigned char keylen);
bool RunPad( int nType, const char * In,unsigned datalen, char * Out,unsigned & padlen);
void SetSubKey(PSubKey pSubKey, const char Key[ 8 ]);
void DES( char Out[ 8 ], char In[ 8 ], const PSubKey pSubKey, bool nType);
bool myRunDES( bool bType, char * In, char * Out,unsigned datalen, const char * Key, const unsigned char keylen);
};
#endif
myDES.cpp
//
DES.cpp: implementation of the myDES class.
//
/ /
#include " myDES.h "
#include " memory.h "
// 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 , 29 , 21 , 13 , 5 , 28 , 20 , 12 , 4
};
// permuted choice key (table)
const char PC2_Table[ 48 ] = {
14 , 17 , 11 , 24 , 1 , 5 , 3 , 28 , 15 , 6 , 21 , 10 ,
23 , 19 , 12 , 4 , 26 , 8 , 16 , 7 , 27 , 20 , 13 , 2 ,
41 , 52 , 31 , 37 , 47 , 55 , 30 , 40 , 51 , 45 , 33 , 48 ,
44 , 49 , 39 , 56 , 34 , 53 , 46 , 42 , 50 , 36 , 29 , 32
};
// number left rotations of pc1
const char LOOP_Table[ 16 ] = {
1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1
};
const char LOOPR_Table[ 16 ] = { 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 0 };
// The (in)famous S-boxes
const char S_Box[ 8 ][ 4 ][ 16 ] = {
// S1
14 , 4 , 13 , 1 , 2 , 15 , 11 , 8 , 3 , 10 , 6 , 12 , 5 , 9 , 0 , 7 ,
0 , 15 , 7 , 4 , 14 , 2 , 13 , 1 , 10 , 6 , 12 , 11 , 9 , 5 , 3 , 8 ,
4 , 1 , 14 , 8 , 13 , 6 , 2 , 11 , 15 , 12 , 9 , 7 , 3 , 10 , 5 , 0 ,
15 , 12 , 8 , 2 , 4 , 9 , 1 , 7 , 5 , 11 , 3 , 14 , 10 , 0 , 6 , 13 ,
// S2
15 , 1 , 8 , 14 , 6 , 11 , 3 , 4 , 9 , 7 , 2 , 13 , 12 , 0 , 5 , 10 ,
3 , 13 , 4 , 7 , 15 , 2 , 8 , 14 , 12 , 0 , 1 , 10 , 6 , 9 , 11 , 5 ,
0 , 14 , 7 , 11 , 10 , 4 , 13 , 1 , 5 , 8 , 12 , 6 , 9 , 3 , 2 , 15 ,
13 , 8 , 10 , 1 , 3 , 15 , 4 , 2 , 11 , 6 , 7 , 12 , 0 , 5 , 14 , 9 ,
// S3
10 , 0 , 9 , 14 , 6 , 3 , 15 , 5 , 1 , 13 , 12 , 7 , 11 , 4 , 2 , 8 ,
13 , 7 , 0 , 9 , 3 , 4 , 6 , 10 , 2 , 8 , 5 , 14 , 12 , 11 , 15 , 1 ,
13 , 6 , 4 , 9 , 8 , 15 , 3 , 0 , 11 , 1 , 2 , 12 , 5 , 10 , 14 , 7 ,
1 , 10 , 13 , 0 , 6 , 9 , 8 , 7 , 4 , 15 , 14 , 3 , 11 , 5 , 2 , 12 ,
// S4
7 , 13 , 14 , 3 , 0 , 6 , 9 , 10 , 1 , 2 , 8 , 5 , 11 , 12 , 4 , 15 ,
13 , 8 , 11 , 5 , 6 , 15 , 0 , 3 , 4 , 7 , 2 , 12 , 1 , 10 , 14 , 9 ,
10 , 6 , 9 , 0 , 12 , 11 , 7 , 13 , 15 , 1 , 3 , 14 , 5 , 2 , 8 , 4 ,
3 , 15 , 0 , 6 , 10 , 1 , 13 , 8 , 9 , 4 , 5 , 11 , 12 , 7 , 2 , 14 ,
// S5
2 , 12 , 4 , 1 , 7 , 10 , 11 , 6 , 8 , 5 , 3 , 15 , 13 , 0 , 14 , 9 ,
14 , 11 , 2 , 12 , 4 , 7 , 13 , 1 , 5 , 0 , 15 , 10 , 3 , 9 , 8 , 6 ,
4 , 2 , 1 , 11 , 10 , 13 , 7 , 8 , 15 , 9 , 12 , 5 , 6 , 3 , 0 , 14 ,
11 , 8 , 12 , 7 , 1 , 14 , 2 , 13 , 6 , 15 , 0 , 9 , 10 , 4 , 5 , 3 ,
// S6
12 , 1 , 10 , 15 , 9 , 2 , 6 , 8 , 0 , 13 , 3 , 4 , 14 , 7 , 5 , 11 ,
10 , 15 , 4 , 2 , 7 , 12 , 9 , 5 , 6 , 1 , 13 , 14 , 0 , 11 , 3 , 8 ,
9 , 14 , 15 , 5 , 2 , 8 , 12 , 3 , 7 , 0 , 4 , 10 , 1 , 13 , 11 , 6 ,
4 , 3 , 2 , 12 , 9 , 5 , 15 , 10 , 11 , 14 , 1 , 7 , 6 , 0 , 8 , 13 ,
// S7
4 , 11 , 2 , 14 , 15 , 0 , 8 , 13 , 3 , 12 , 9 , 7 , 5 , 10 , 6 , 1 ,
13 , 0 , 11 , 7 , 4 , 9 , 1 , 10 , 14 , 3 , 5 , 12 , 2 , 15 , 8 , 6 ,
1 , 4 , 11 , 13 , 12 , 3 , 7 , 14 , 10 , 15 , 6 , 8 , 0 , 5 , 9 , 2 ,
6 , 11 , 13 , 8 , 1 , 4 , 10 , 7 , 9 , 5 , 0 , 15 , 14 , 2 , 3 , 12 ,
// S8
13 , 2 , 8 , 4 , 6 , 15 , 11 , 1 , 10 , 9 , 3 , 14 , 5 , 0 , 12 , 7 ,
1 , 15 , 13 , 8 , 10 , 3 , 7 , 4 , 12 , 5 , 6 , 11 , 0 , 14 , 9 , 2 ,
7 , 11 , 4 , 1 , 9 , 12 , 14 , 2 , 0 , 6 , 10 , 13 , 15 , 3 , 5 , 8 ,
2 , 1 , 14 , 7 , 4 , 10 , 8 , 13 , 15 , 12 , 9 , 0 , 3 , 5 , 6 , 11
};
myDES::myDES()
{
}
myDES:: ~ myDES()
{
}
/* ***************************************************************** */
/*
函 数 名 称: ByteToBit
功 能 描 述: 把BYTE转化为Bit流
参 数 说 明: Out: 输出的Bit流[in][out]
In: 输入的BYTE流[in]
bits: Bit流的长度[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::ByteToBit( bool * Out, const char * In, int bits)
{
for ( int i = 0 ; i < bits; ++ i)
Out[i] = (In[i >> 3 ] >> ( 7 - i & 7 )) & 1 ;
}
/* ***************************************************************** */
/*
函 数 名 称: BitToByte
功 能 描 述: 把Bit转化为Byte流
参 数 说 明: Out: 输出的BYTE流[in][out]
In: 输入的Bit流[in]
bits: Bit流的长度[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES:: BitToByte( char * Out, const bool * In, int bits)
{
memset(Out, 0 , bits >> 3 );
for ( int i = 0 ; i < bits; ++ i)
Out[i >> 3 ] |= In[i] << ( 7 - i & 7 );
}
/* ***************************************************************** */
/*
函 数 名 称: RotateL
功 能 描 述: 把BIT流按位向左迭代
参 数 说 明: In: 输入的Bit流[in]
len: Bit流的长度[in]
loop: 向左迭代的长度
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::RotateL( bool * In, int len, int loop)
{
bool Tmp[ 256 ];
memcpy(Tmp, In, loop);
memcpy(In, In + loop, len - loop);
memcpy(In + len - loop, Tmp, loop);
}
void myDES::RotateR( bool * In, int len, int loop)
{
bool Tmp[ 256 ];
memcpy(Tmp,In,len - loop);
memcpy(In,In + len - loop,loop);
memcpy(In + len - loop,Tmp,len - loop);
}
/* ***************************************************************** */
/*
函 数 名 称: Xor
功 能 描 述: 把两个Bit流进行异或
参 数 说 明: InA: 输入的Bit流[in][out]
InB: 输入的Bit流[in]
loop: Bit流的长度
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::Xor( bool * InA, const bool * InB, int len)
{
for ( int i = 0 ; i < len; ++ i)
InA[i] ^= InB[i];
}
/* ***************************************************************** */
/*
函 数 名 称: Transform
功 能 描 述: 把两个Bit流按表进行位转化
参 数 说 明: Out: 输出的Bit流[out]
In: 输入的Bit流[in]
Table: 转化需要的表指针
len: 转化表的长度
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::Transform( bool * Out, bool * In, const char * Table, int len)
{
bool Tmp[ 256 ];
for ( int i = 0 ; i < len; ++ i)
Tmp[i] = In[ Table[i] - 1 ];
memcpy(Out, Tmp, len);
}
/* ***************************************************************** */
/*
函 数 名 称: S_func
功 能 描 述: 实现数据加密S BOX模块
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::S_func( bool Out[ 32 ], const bool In[ 48 ])
{
for ( char i = 0 ,j,k; i < 8 ; ++ i,In += 6 ,Out += 4 )
{
j = (In[ 0 ] << 1 ) + In[ 5 ];
k = (In[ 1 ] << 3 ) + (In[ 2 ] << 2 ) + (In[ 3 ] << 1 ) + In[ 4 ]; // 组织SID下标
for ( int l = 0 ; l < 4 ; ++ l) // 把相应4bit赋值
Out[l] = (S_Box[i][j][k] >> ( 3 - l)) & 1 ;
}
}
/* ***************************************************************** */
/*
函 数 名 称: F_func
功 能 描 述: 实现数据加密到输出P
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::F_func( bool In[ 32 ], const bool Ki[ 48 ])
{
bool MR[ 48 ];
Transform(MR, In, E_Table, 48 );
Xor(MR, Ki, 48 );
S_func(In, MR);
Transform(In, In, P_Table, 32 );
}
/* ***************************************************************** */
/*
函 数 名 称: RunDes
功 能 描 述: 执行DES算法对文本加解密
参 数 说 明: bType :类型:加密ENCRYPT,解密DECRYPT
bMode :模式:ECB,CBC
In :待加密串指针
Out :待输出串指针
datalen :待加密串的长度,同时Out的缓冲区大小应大于或者等于datalen
Key :密钥(可为8位,16位,24位)支持3密钥
keylen :密钥长度,多出24位部分将被自动裁减
返回值 说明: bool :是否加密成功
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
bool myDES::RunDes( bool bType, 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 ]);
}
// 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);
}
}
return true ;
}
/* ***************************************************************** */
/*
函 数 名 称: RunPad
功 能 描 述: 根据协议对加密前的数据进行填充
参 数 说 明: bType :类型:PAD类型
In :数据串指针
Out :填充输出串指针
datalen :数据的长度
padlen :(in,out)输出buffer的长度,填充后的长度
返回值 说明: bool :是否填充成功
作 者: 邹德强
修 改 历 史:
更 新 日 期: 2003.12.19
/****************************************************************** */
/* bool myDES::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;
}
} */
bool myDES::RunPad( int nType, const char * In,unsigned datalen, char * Out,unsigned & padlen)
{
int res = (datalen & 0x00000007 );
memcpy(Out,In,datalen);
if (res)
{
memset(Out + datalen, 0x00 , 8 - res);
return true ;
}
else
{
return false ;
}
}
// 计算并填充子密钥到SubKey数据中
void myDES::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 myDES::DES( char Out[ 8 ], char In[ 8 ], const PSubKey pSubKey, bool nType)
{
bool M[ 64 ], tmp[ 32 ], * Li =& M[ 0 ], * Ri =& M[ 32 ];
ByteToBit(M, In, 64 );
Transform(M, M, IP_Table, 64 );
if ( nType )
{
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 ); // 组织成字符
}
bool myDES::myRunDES( bool bType, char * In, char * Out,unsigned datalen, const char * Key, const unsigned char keylen)
{
return true ;
}
//
/ /
#include " myDES.h "
#include " memory.h "
// 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 , 29 , 21 , 13 , 5 , 28 , 20 , 12 , 4
};
// permuted choice key (table)
const char PC2_Table[ 48 ] = {
14 , 17 , 11 , 24 , 1 , 5 , 3 , 28 , 15 , 6 , 21 , 10 ,
23 , 19 , 12 , 4 , 26 , 8 , 16 , 7 , 27 , 20 , 13 , 2 ,
41 , 52 , 31 , 37 , 47 , 55 , 30 , 40 , 51 , 45 , 33 , 48 ,
44 , 49 , 39 , 56 , 34 , 53 , 46 , 42 , 50 , 36 , 29 , 32
};
// number left rotations of pc1
const char LOOP_Table[ 16 ] = {
1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1
};
const char LOOPR_Table[ 16 ] = { 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 0 };
// The (in)famous S-boxes
const char S_Box[ 8 ][ 4 ][ 16 ] = {
// S1
14 , 4 , 13 , 1 , 2 , 15 , 11 , 8 , 3 , 10 , 6 , 12 , 5 , 9 , 0 , 7 ,
0 , 15 , 7 , 4 , 14 , 2 , 13 , 1 , 10 , 6 , 12 , 11 , 9 , 5 , 3 , 8 ,
4 , 1 , 14 , 8 , 13 , 6 , 2 , 11 , 15 , 12 , 9 , 7 , 3 , 10 , 5 , 0 ,
15 , 12 , 8 , 2 , 4 , 9 , 1 , 7 , 5 , 11 , 3 , 14 , 10 , 0 , 6 , 13 ,
// S2
15 , 1 , 8 , 14 , 6 , 11 , 3 , 4 , 9 , 7 , 2 , 13 , 12 , 0 , 5 , 10 ,
3 , 13 , 4 , 7 , 15 , 2 , 8 , 14 , 12 , 0 , 1 , 10 , 6 , 9 , 11 , 5 ,
0 , 14 , 7 , 11 , 10 , 4 , 13 , 1 , 5 , 8 , 12 , 6 , 9 , 3 , 2 , 15 ,
13 , 8 , 10 , 1 , 3 , 15 , 4 , 2 , 11 , 6 , 7 , 12 , 0 , 5 , 14 , 9 ,
// S3
10 , 0 , 9 , 14 , 6 , 3 , 15 , 5 , 1 , 13 , 12 , 7 , 11 , 4 , 2 , 8 ,
13 , 7 , 0 , 9 , 3 , 4 , 6 , 10 , 2 , 8 , 5 , 14 , 12 , 11 , 15 , 1 ,
13 , 6 , 4 , 9 , 8 , 15 , 3 , 0 , 11 , 1 , 2 , 12 , 5 , 10 , 14 , 7 ,
1 , 10 , 13 , 0 , 6 , 9 , 8 , 7 , 4 , 15 , 14 , 3 , 11 , 5 , 2 , 12 ,
// S4
7 , 13 , 14 , 3 , 0 , 6 , 9 , 10 , 1 , 2 , 8 , 5 , 11 , 12 , 4 , 15 ,
13 , 8 , 11 , 5 , 6 , 15 , 0 , 3 , 4 , 7 , 2 , 12 , 1 , 10 , 14 , 9 ,
10 , 6 , 9 , 0 , 12 , 11 , 7 , 13 , 15 , 1 , 3 , 14 , 5 , 2 , 8 , 4 ,
3 , 15 , 0 , 6 , 10 , 1 , 13 , 8 , 9 , 4 , 5 , 11 , 12 , 7 , 2 , 14 ,
// S5
2 , 12 , 4 , 1 , 7 , 10 , 11 , 6 , 8 , 5 , 3 , 15 , 13 , 0 , 14 , 9 ,
14 , 11 , 2 , 12 , 4 , 7 , 13 , 1 , 5 , 0 , 15 , 10 , 3 , 9 , 8 , 6 ,
4 , 2 , 1 , 11 , 10 , 13 , 7 , 8 , 15 , 9 , 12 , 5 , 6 , 3 , 0 , 14 ,
11 , 8 , 12 , 7 , 1 , 14 , 2 , 13 , 6 , 15 , 0 , 9 , 10 , 4 , 5 , 3 ,
// S6
12 , 1 , 10 , 15 , 9 , 2 , 6 , 8 , 0 , 13 , 3 , 4 , 14 , 7 , 5 , 11 ,
10 , 15 , 4 , 2 , 7 , 12 , 9 , 5 , 6 , 1 , 13 , 14 , 0 , 11 , 3 , 8 ,
9 , 14 , 15 , 5 , 2 , 8 , 12 , 3 , 7 , 0 , 4 , 10 , 1 , 13 , 11 , 6 ,
4 , 3 , 2 , 12 , 9 , 5 , 15 , 10 , 11 , 14 , 1 , 7 , 6 , 0 , 8 , 13 ,
// S7
4 , 11 , 2 , 14 , 15 , 0 , 8 , 13 , 3 , 12 , 9 , 7 , 5 , 10 , 6 , 1 ,
13 , 0 , 11 , 7 , 4 , 9 , 1 , 10 , 14 , 3 , 5 , 12 , 2 , 15 , 8 , 6 ,
1 , 4 , 11 , 13 , 12 , 3 , 7 , 14 , 10 , 15 , 6 , 8 , 0 , 5 , 9 , 2 ,
6 , 11 , 13 , 8 , 1 , 4 , 10 , 7 , 9 , 5 , 0 , 15 , 14 , 2 , 3 , 12 ,
// S8
13 , 2 , 8 , 4 , 6 , 15 , 11 , 1 , 10 , 9 , 3 , 14 , 5 , 0 , 12 , 7 ,
1 , 15 , 13 , 8 , 10 , 3 , 7 , 4 , 12 , 5 , 6 , 11 , 0 , 14 , 9 , 2 ,
7 , 11 , 4 , 1 , 9 , 12 , 14 , 2 , 0 , 6 , 10 , 13 , 15 , 3 , 5 , 8 ,
2 , 1 , 14 , 7 , 4 , 10 , 8 , 13 , 15 , 12 , 9 , 0 , 3 , 5 , 6 , 11
};
myDES::myDES()
{
}
myDES:: ~ myDES()
{
}
/* ***************************************************************** */
/*
函 数 名 称: ByteToBit
功 能 描 述: 把BYTE转化为Bit流
参 数 说 明: Out: 输出的Bit流[in][out]
In: 输入的BYTE流[in]
bits: Bit流的长度[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::ByteToBit( bool * Out, const char * In, int bits)
{
for ( int i = 0 ; i < bits; ++ i)
Out[i] = (In[i >> 3 ] >> ( 7 - i & 7 )) & 1 ;
}
/* ***************************************************************** */
/*
函 数 名 称: BitToByte
功 能 描 述: 把Bit转化为Byte流
参 数 说 明: Out: 输出的BYTE流[in][out]
In: 输入的Bit流[in]
bits: Bit流的长度[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES:: BitToByte( char * Out, const bool * In, int bits)
{
memset(Out, 0 , bits >> 3 );
for ( int i = 0 ; i < bits; ++ i)
Out[i >> 3 ] |= In[i] << ( 7 - i & 7 );
}
/* ***************************************************************** */
/*
函 数 名 称: RotateL
功 能 描 述: 把BIT流按位向左迭代
参 数 说 明: In: 输入的Bit流[in]
len: Bit流的长度[in]
loop: 向左迭代的长度
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::RotateL( bool * In, int len, int loop)
{
bool Tmp[ 256 ];
memcpy(Tmp, In, loop);
memcpy(In, In + loop, len - loop);
memcpy(In + len - loop, Tmp, loop);
}
void myDES::RotateR( bool * In, int len, int loop)
{
bool Tmp[ 256 ];
memcpy(Tmp,In,len - loop);
memcpy(In,In + len - loop,loop);
memcpy(In + len - loop,Tmp,len - loop);
}
/* ***************************************************************** */
/*
函 数 名 称: Xor
功 能 描 述: 把两个Bit流进行异或
参 数 说 明: InA: 输入的Bit流[in][out]
InB: 输入的Bit流[in]
loop: Bit流的长度
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::Xor( bool * InA, const bool * InB, int len)
{
for ( int i = 0 ; i < len; ++ i)
InA[i] ^= InB[i];
}
/* ***************************************************************** */
/*
函 数 名 称: Transform
功 能 描 述: 把两个Bit流按表进行位转化
参 数 说 明: Out: 输出的Bit流[out]
In: 输入的Bit流[in]
Table: 转化需要的表指针
len: 转化表的长度
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::Transform( bool * Out, bool * In, const char * Table, int len)
{
bool Tmp[ 256 ];
for ( int i = 0 ; i < len; ++ i)
Tmp[i] = In[ Table[i] - 1 ];
memcpy(Out, Tmp, len);
}
/* ***************************************************************** */
/*
函 数 名 称: S_func
功 能 描 述: 实现数据加密S BOX模块
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::S_func( bool Out[ 32 ], const bool In[ 48 ])
{
for ( char i = 0 ,j,k; i < 8 ; ++ i,In += 6 ,Out += 4 )
{
j = (In[ 0 ] << 1 ) + In[ 5 ];
k = (In[ 1 ] << 3 ) + (In[ 2 ] << 2 ) + (In[ 3 ] << 1 ) + In[ 4 ]; // 组织SID下标
for ( int l = 0 ; l < 4 ; ++ l) // 把相应4bit赋值
Out[l] = (S_Box[i][j][k] >> ( 3 - l)) & 1 ;
}
}
/* ***************************************************************** */
/*
函 数 名 称: F_func
功 能 描 述: 实现数据加密到输出P
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
void myDES::F_func( bool In[ 32 ], const bool Ki[ 48 ])
{
bool MR[ 48 ];
Transform(MR, In, E_Table, 48 );
Xor(MR, Ki, 48 );
S_func(In, MR);
Transform(In, In, P_Table, 32 );
}
/* ***************************************************************** */
/*
函 数 名 称: RunDes
功 能 描 述: 执行DES算法对文本加解密
参 数 说 明: bType :类型:加密ENCRYPT,解密DECRYPT
bMode :模式:ECB,CBC
In :待加密串指针
Out :待输出串指针
datalen :待加密串的长度,同时Out的缓冲区大小应大于或者等于datalen
Key :密钥(可为8位,16位,24位)支持3密钥
keylen :密钥长度,多出24位部分将被自动裁减
返回值 说明: bool :是否加密成功
作 者: 邹德强
更 新 日 期: 2003.12.19
/****************************************************************** */
bool myDES::RunDes( bool bType, 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 ]);
}
// 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);
}
}
return true ;
}
/* ***************************************************************** */
/*
函 数 名 称: RunPad
功 能 描 述: 根据协议对加密前的数据进行填充
参 数 说 明: bType :类型:PAD类型
In :数据串指针
Out :填充输出串指针
datalen :数据的长度
padlen :(in,out)输出buffer的长度,填充后的长度
返回值 说明: bool :是否填充成功
作 者: 邹德强
修 改 历 史:
更 新 日 期: 2003.12.19
/****************************************************************** */
/* bool myDES::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;
}
} */
bool myDES::RunPad( int nType, const char * In,unsigned datalen, char * Out,unsigned & padlen)
{
int res = (datalen & 0x00000007 );
memcpy(Out,In,datalen);
if (res)
{
memset(Out + datalen, 0x00 , 8 - res);
return true ;
}
else
{
return false ;
}
}
// 计算并填充子密钥到SubKey数据中
void myDES::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 myDES::DES( char Out[ 8 ], char In[ 8 ], const PSubKey pSubKey, bool nType)
{
bool M[ 64 ], tmp[ 32 ], * Li =& M[ 0 ], * Ri =& M[ 32 ];
ByteToBit(M, In, 64 );
Transform(M, M, IP_Table, 64 );
if ( nType )
{
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 ); // 组织成字符
}
bool myDES::myRunDES( bool bType, char * In, char * Out,unsigned datalen, const char * Key, const unsigned char keylen)
{
return true ;
}