#if !defined(_CRYPT3DES_H)
#define _CRYPT3DES_H
#if !defined(ED_FLAG)
#define ED_FLAG
#define encrypt 0
#define decrypt 1
#endif
#ifndef _WINDOWS_
#include "windows.h"
#endif
//////////////////////////////////////////////////////////////////////////
/*
unsigned char key[8] = {"doks"};
unsigned char buff[8] = {"abcdef"};
C3DES des;
des.DoDES3(0,buff,key);
des.DoDES3(1,buff,key);
*/
/* 3DES Class. */
class C3DES
{
public:
BOOL DoDES3(int nWay,unsigned char* pSrc,int nSrcSize,unsigned char* pDes,unsigned char pKey[8]);
private:
BOOL DoDES3(
unsigned char EDFlag, //EDFlag是加\脱密标志,0表示加密,1表示脱密
unsigned char databuf[8], //DataBuf将被处理的明文或密文的缓冲区,并兼作输出缓冲区
unsigned char keybuf[8] //8byte的密钥缓冲区
);
inline void pro_key(void);
inline void first_p(void);
inline void expand_x(void);
inline void fction(void);
inline void make(BOOL FirstFlag);
static const unsigned long sp0[64],sp1[64],sp2[64],sp3[64],sp4[64],sp5[64],sp6[64],sp7[64];
static const unsigned char pc0[64],pc0_v[64],pc1[56],pc2[48],rotate[16],bytebit[8];
static const unsigned long bigbyte[24],bigbyte1[32];
unsigned char key[8],m[8],c[8],k[16][8],s_in[8],pc[64];
unsigned char ed_flag;
unsigned long x[2];
};
#endif
#include "stdafx.h"
#include "3DES.h"
const unsigned long C3DES::sp0[64]={0x00808200,0x00000000,0x00008000,0x00808202,
0x00808002,0x00008202,0x00000002,0x00008000,
0x00000200,0x00808200,0x00808202,0x00000200,
0x00800202,0x00808002,0x00800000,0x00000002,
0x00000202,0x00800200,0x00800200,0x00008200,
0x00008200,0x00808000,0x00808000,0x00800202,
0x00008002,0x00800002,0x00800002,0x00008002,
0x00000000,0x00000202,0x00008202,0x00800000,
0x00008000,0x00808202,0x00000002,0x00808000,
0x00808200,0x00800000,0x00800000,0x00000200,
0x00808002,0x00008000,0x00008200,0x00800002,
0x00000200,0x00000002,0x00800202,0x00008202,
0x00808202,0x00008002,0x00808000,0x00800202,
0x00800002,0x00000202,0x00008202,0x00808200,
0x00000202,0x00800200,0x00800200,0x00000000,
0x00008002,0x00008200,0x00000000,0x00808002},
C3DES::sp1[64]={0x40084010,0x40004000,0x00004000,0x00084010,
0x00080000,0x00000010,0x40080010,0x40004010,
0x40000010,0x40084010,0x40084000,0x40000000,
0x40004000,0x00080000,0x00000010,0x40080010,
0x00084000,0x00080010,0x40004010,0x00000000,
0x40000000,0x00004000,0x00084010,0x40080000,
0x00080010,0x40000010,0x00000000,0x00084000,
0x4010,0x40084000,0x40080000,0x4010,
0x0,0x84010,0x40080010,0x80000,
0x40004010,0x40080000,0x40084000,0x4000,
0x40080000,0x40004000,0x10,0x40084010,
0x84010,0x10,0x4000,0x40000000,
0x4010,0x40084000,0x80000,0x40000010,
0x80010,0x40004010,0x40000010,0x80010,
0x84000,0x0,0x40004000,0x4010,
0x40000000,0x40080010,0x40084010,0x84000},
C3DES::sp2[64]={0x104,0x4010100,0x0,0x4010004,
0x4000100,0x0,0x10104,0x4000100,
0x10004,0x4000004,0x4000004,0x10000,
0x4010104,0x10004,0x4010000,0x104,
0x4000000,0x4,0x4010100,0x100,
0x10100,0x4010000,0x4010004,0x10104,
0x4000104,0x10100,0x10000,0x4000104,
0x4,0x4010104,0x100,0x4000000,
0x4010100,0x4000000,0x10004,0x104,
0x10000,0x4010100,0x4000100,0x0,
0x100,0x10004,0x4010104,0x4000100,
0x4000004,0x100,0x0,0x4010004,
0x4000104,0x10000,0x4000000,0x4010104,
0x4,0x10104,0x10100,0x4000004,
0x4010000,0x4000104,0x104,0x4010000,
0x10104,0x4,0x4010004,0x10100},
C3DES::sp3[64]={0x80401000,0x80001040,0x80001040,0x40,
0x401040,0x80400040,0x80400000,0x80001000,
0x0,0x401000,0x401000,0x80401040,
0x80000040,0x0,0x400040,0x80400000,
0x80000000,0x1000,0x400000,0x80401000,
0x40,0x400000,0x80001000,0x1040,
0x80400040,0x80000000,0x1040,0x400040,
0x1000,0x401040,0x80401040,0x80000040,
0x400040,0x80400000,0x401000,0x80401040,
0x80000040,0x0,0x0,0x401000,
0x1040,0x400040,0x80400040,0x80000000,
0x80401000,0x80001040,0x80001040,0x40,
0x80401040,0x80000040,0x80000000,0x1000,
0x80400000,0x80001000,0x401040,0x80400040,
0x80001000,0x1040,0x400000,0x80401000,
0x40,0x400000,0x1000,0x401040},
C3DES::sp4[64]={0x80,0x1040080,0x1040000,0x21000080,
0x40000,0x80,0x20000000,0x1040000,
0x20040080,0x40000,0x1000080,0x20040080,
0x21000080,0x21040000,0x40080,0x20000000,
0x1000000,0x20040000,0x20040000,0x0,
0x20000080,0x21040080,0x21040080,0x1000080,
0x21040000,0x20000080,0x0,0x21000000,
0x1040080,0x1000000,0x21000000,0x40080,
0x40000,0x21000080,0x80,0x1000000,
0x20000000,0x1040000,0x21000080,0x20040080,
0x1000080,0x20000000,0x21040000,0x1040080,
0x20040080,0x80,0x1000000,0x21040000,
0x21040080,0x40080,0x21000000,0x21040080,
0x1040000,0x0,0x20040000,0x21000000,
0x40080,0x1000080,0x20000080,0x40000,
0x0,0x20040000,0x1040080,0x20000080},
C3DES::sp5[64]={0x10000008,0x10200000,0x2000,0x10202008,
0x10200000,0x8,0x10202008,0x200000,
0x10002000,0x202008,0x200000,0x10000008,
0x200008,0x10002000,0x10000000,0x2008,
0x0,0x200008,0x10002008,0x2000,
0x202000,0x10002008,0x8,0x10200008,
0x10200008,0x0,0x202008,0x10202000,
0x2008,0x202000,0x10202000,0x10000000,
0x10002000,0x8,0x10200008,0x202000,
0x10202008,0x200000,0x2008,0x10000008,
0x200000,0x10002000,0x10000000,0x2008,
0x10000008,0x10202008,0x202000,0x10200000,
0x202008,0x10202000,0x0,0x10200008,
0x8,0x2000,0x10200000,0x202008,
0x2000,0x200008,0x10002008,0x0,
0x10202000,0x10000000,0x200008,0x10002008},
C3DES::sp6[64]={0x100000,0x2100001,0x2000401,0x0,
0x400,0x2000401,0x100401,0x2100400,
0x2100401,0x100000,0x0,0x2000001,
0x1,0x2000000,0x2100001,0x401,
0x2000400,0x100401,0x100001,0x2000400,
0x2000001,0x2100000,0x2100400,0x100001,
0x2100000,0x400,0x401,0x2100401,
0x100400,0x1,0x2000000,0x100400,
0x2000000,0x100400,0x100000,0x2000401,
0x2000401,0x2100001,0x2100001,0x1,
0x100001,0x2000000,0x2000400,0x100000,
0x2100400,0x401,0x100401,0x2100400,
0x401,0x2000001,0x2100401,0x2100000,
0x100400,0x0,0x1,0x2100401,
0x0,0x100401,0x2100000,0x400,
0x2000001,0x2000400,0x400,0x100001},
C3DES::sp7[64]={0x8000820,0x800,0x20000,0x8020820,
0x8000000,0x8000820,0x20,0x8000000,
0x20020,0x8020000,0x8020820,0x20800,
0x8020800,0x20820,0x800,0x20,
0x8020000,0x8000020,0x8000800,0x820,
0x20800,0x20020,0x8020020,0x8020800,
0x820,0x0,0x0,0x8020020,
0x8000020,0x8000800,0x20820,0x20000,
0x20820,0x20000,0x8020800,0x800,
0x20,0x8020020,0x800,0x20820,
0x8000800,0x20,0x8000020,0x8020000,
0x8020020,0x8000000,0x20000,0x8000820,
0x0,0x8020820,0x20020,0x8000020,
0x8020000,0x8000800,0x8000820,0x0,
0x8020820,0x20800,0x20800,0x820,
0x820,0x20020,0x8000000,0x8020800};
const unsigned char C3DES::pc0[64]={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,
56,48,40,32,24,16, 8, 0,58,50,42,34,26,18,10, 2,
60,52,44,36,28,20,12, 4,62,54,46,38,30,22,14, 6},
C3DES::pc0_v[64]={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,32, 0,40, 8,48,16,56,24};
const unsigned char C3DES::pc1[56]={56,48,40,32,24,16, 8, 0,57,49,41,33,25,17,
9, 1,58,50,42,34,26,18,10, 2,59,51,43,35,
62,54,46,38,30,22,14, 6,61,53,45,37,29,21,
13, 5,60,52,44,36,28,20,12, 4,27,19,11, 3},
C3DES::pc2[48]={13,16,10,23, 0, 4, 2,27,14, 5,20, 9,
22,18,11, 3,25, 7,15, 6,26,19,12, 1,
40,51,30,36,46,54,29,39,50,44,32,47,
43,48,38,55,33,52,45,41,49,35,28,31},
C3DES::rotate[16]={1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28};
const unsigned char C3DES::bytebit[8]={0200,0100,040,020,010,04,02,01};//八进制数据
const unsigned long C3DES::bigbyte[24]={0x800000,0x400000,0x200000,0x100000,
0x80000, 0x40000, 0x20000, 0x10000,
0x8000, 0x4000, 0x2000, 0x1000,
0x800, 0x400, 0x200, 0x100,
0x80, 0x40, 0x20, 0x10,
0x8, 0x4, 0x2, 0x1},
C3DES::bigbyte1[32]={0x80000000,0x40000000,0x20000000,0x10000000,
0x8000000, 0x4000000, 0x2000000, 0x1000000,
0x800000, 0x400000, 0x200000, 0x100000,
0x80000, 0x40000, 0x20000, 0x10000,
0x8000, 0x4000, 0x2000, 0x1000,
0x800, 0x400, 0x200, 0x100,
0x80, 0x40, 0x20, 0x10,
0x8, 0x4, 0x2, 0x1};
void C3DES::make(BOOL FirstFlag)
//操作过程:根据事先预置在key[8],m[8],ed_flag中的数据进行
//加密\脱密操作,将结果保存在c[8]中。参数FirstFlag标识m[8]中
//是否是首块数据。
{
unsigned int j;
if(FirstFlag==TRUE) pro_key();
for(j=0;j<64;j++) pc[j]=pc0[j];
first_p();
fction();
unsigned char *pointer=(unsigned char *)x;
for(j=0;j<4;j++)
m[3-j]=*pointer++;
for(j=0;j<4;j++)
m[7-j]=*pointer++;
for(j=0;j<64;j++) pc[j]=pc0_v[j];
first_p();
pointer=(unsigned char *)x;
for(j=0;j<4;j++)
c[3-j]=*pointer++;
for(j=0;j<4;j++)
c[7-j]=*pointer++;
}
void C3DES::pro_key(void)
//操作过程:以pc1[56],pc2[48],bytebit[8],bigbyte[24],
//rotate[16]及key[8]中的数据为入参,进行运算后得到结果保存
//到k[16][8]中,并根据ed_flag的值是否是decrypt来决定是否对
//k[16][8]中的结果进行调整。
{
unsigned short i,j,l;
unsigned char pc1m[56],pcr[56],k_m[16][8];
unsigned long k1[16],k2[16];
for(j=0;j<56;j++)
{
l=pc1[j];
pc1m[j]=(key[l>>3]&bytebit[l&07]) ? 1:0 ;
//所有能使(l & 0x07)的值为7即用来访问bytebit[7]
//的l值有:7,15,23,31,39,47,55,63,而这些值在pc1[56]
//的定义中都没有。也就是说bytebit[7](=0x01)永远
//无法被访问。因此密钥key[8]的各字节数据的最低位
//总是被忽略。
}
for(i=0;i<16;i++)
{
k1[i]=k2[i]=0;
for(j=0;j<28;j++)
{
l=j+rotate[i];
if(l<28) pcr[j]=pc1m[l];
else pcr[j]=pc1m[l-28];
}
for(j=28;j<56;j++)
{
l=j+rotate[i];
if(l<56) pcr[j]=pc1m[l];
else pcr[j]=pc1m[l-28];
}
for(j=0;j<24;j++)
{
if(pcr[pc2[j]]) k1[i]|=bigbyte[j];
if(pcr[pc2[j+24]]) k2[i]|=bigbyte[j];
}
k[i][0]=(unsigned char)((k1[i]>>18)&0x3f);
k[i][1]=(unsigned char)((k1[i]>>12)&0x3f);
k[i][2]=(unsigned char)((k1[i]>>6)&0x3f);
k[i][3]=(unsigned char)(k1[i]&0x3f);
k[i][4]=(unsigned char)((k2[i]>>18)&0x3f);
k[i][5]=(unsigned char)((k2[i]>>12)&0x3f);
k[i][6]=(unsigned char)((k2[i]>>6)&0x3f);
k[i][7]=(unsigned char)(k2[i]&0x3f);
}
if(ed_flag==decrypt)
{
for(i=0;i<16;i++)
for(j=0;j<8;j++) k_m[i][j]=k[15-i][j];
for(i=0;i<16;i++)
for(j=0;j<8;j++) k[i][j]=k_m[i][j];
}
}
void C3DES::first_p(void)
//操作过程:以bytebit[8],bigbyte1[32],pc[64]及m[8]中的数据
//为入参,进行运算后得到结果保存到x[2]中。
{
unsigned char pcm[64];
unsigned short j,l;
x[0]=x[1]=0;
for(j=0;j<64;j++)
{
l=pc[j];
pcm[j]=(m[l>>3]&bytebit[l&07]) ? 1:0;
}
for(j=0;j<32;j++)
{
if(pcm[j]) x[0]|=bigbyte1[j];
if(pcm[j+32]) x[1]|=bigbyte1[j];
}
}
void C3DES::expand_x(void)
//操作过程:以数组x[2]中的数据元素x[1]的值为入参,进行运算
//后得到结果保存到s_in[8]中。
{
s_in[0]=(unsigned char)((x[1]>>27)^((x[1]&0x1)<<5));
s_in[1]=(unsigned char)((x[1]&0x1f800000)>>23);
s_in[2]=(unsigned char)((x[1]&0x1f80000)>>19);
s_in[3]=(unsigned char)((x[1]&0x1f8000)>>15);
s_in[4]=(unsigned char)((x[1]&0x1f800)>>11);
s_in[5]=(unsigned char)((x[1]&0x1f80)>>7);
s_in[6]=(unsigned char)((x[1]&0x1f8)>>3);
s_in[7]=(unsigned char)(((x[1]&0x1f)<<1)^(x[1]>>31));
}
void C3DES::fction(void)
//操作过程:以sp0[64],sp1[64],sp2[64],sp3[64],sp4[64],
//sp5[64],sp6[64],sp7[64]及x[2],k[16][8],s_in[8]中的数
//据为入参,进行运算后得到结果保存到x[2]中。
{
unsigned short i,j;
unsigned long xm;
for(i=0;i<16;i++)
{
xm=x[1];
expand_x();
for(j=0;j<8;j++) s_in[j]^=k[i][j];
x[1] =sp0[s_in[0]];
x[1]^=sp1[s_in[1]];
x[1]^=sp2[s_in[2]];
x[1]^=sp3[s_in[3]];
x[1]^=sp4[s_in[4]];
x[1]^=sp5[s_in[5]];
x[1]^=sp6[s_in[6]];
x[1]^=sp7[s_in[7]];
x[1]=x[0]^x[1];
x[0]=xm;
}
xm=x[1];
x[1]=x[0];
x[0]=xm;
}
BOOL C3DES::DoDES3(
unsigned char EDFlag, //EDFlag是加\脱密标志,0表示加密,1表示脱密
unsigned char databuf[8], //DataBuf将被处理的明文或密文的缓冲区,并兼作输出缓冲区
unsigned char keybuf[8] //8byte的密钥缓冲区
)
{
ed_flag=EDFlag;
//初始化密钥
memcpy(key, keybuf, 8);
//将64 bit待处理数据置入m[8]
memcpy(m, databuf, 8);
//主加密\脱密算法
make(TRUE);
memcpy(databuf, c, 8);
return TRUE;
}
BOOL C3DES::DoDES3(int nWay,unsigned char* pSrc,int nSrcSize,unsigned char* pDes,unsigned char pKey[8])
{
int nSize = nSrcSize / 8 * 8;
if (nSize < nSrcSize) nSize += 8;
unsigned char* pBuff = new unsigned char[nSize];
ZeroMemory(pBuff,nSize);
memcpy(pBuff,pSrc,nSrcSize);
int i;
unsigned char *p = pBuff;
for (i = 0 ; i < nSize / 8; ++i)
{
if (FALSE == DoDES3(nWay,p,pKey)) return FALSE;
p += 8;
}
memcpy(pDes,pBuff,nSize);
delete[] pBuff;
return TRUE;
}