分享

CSDN技术中心 一个从网上搜到的3DES加解密C++代码

 weicat 2009-11-24
标题   一个从网上搜到的3DES加解密C++代码     选择自 JasonHeung 的 Blog
关键字   一个从网上搜到的3DES加解密C++代码
出处  
 

#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;
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多