⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 des.txt

📁 偶尔想到数据加密技术,这里顺便提一下双向加密的标准DES。以前在一个宽带流媒体服务器项目中用到了DES加密
💻 TXT
📖 第 1 页 / 共 2 页
字号:
偶尔想到数据加密技术,这里顺便提一下双向加密的标准DES。以前在一个宽带流媒体服务器项目中用到了DES加密,虽然使用环境相对单纯,但算法实现本身是具有普遍意义的。下述程序是很久以前在RSA公司的网站找到的,效率很高,稳定性较好,便一直在实践中使用。

首先在头文件中定义一个DES类:

//des.h

#ifndef __DES_H
#define __DES_H
class DES{
public:
    // Encrypt/decrypt the data in "data", according to the "key".
    // Caller is responsible for confirming the buffer size of "data"
    // points to is 8*"blocks" bytes.
    // The data encrypted/decrypted is stored in data.
    // The return code is 1:success, other:failed.

    int encrypt ( unsigned char key[8], unsigned char* data, int blocks = 1 );
    int decrypt ( unsigned char key[8], unsigned char* data, int blocks = 1 );

    // Encrypt/decrypt any size data,according to a special method. 
    // Before calling yencrypt, copy data to a new buffer with size
    // calculated by extend.

    int yencrypt ( unsigned char key[8], unsigned char* data, int size );
    int ydecrypt ( unsigned char key[8], unsigned char* in, int blocks, int* size = 0 );
    int extend ( int size ) { return (size/8+1)*8; };

private:
    void des(unsigned char* in, unsigned char* out, int blocks);
    void des_block(unsigned char* in, unsigned char* out);

private:
    unsigned long KnL[32];
    enum Mode { ENCRYPT, DECRYPT };
    void deskey(unsigned char key[8], Mode md);
    void usekey(unsigned long *);
    void cookey(unsigned long *);

private:
    void scrunch(unsigned char *, unsigned long *);
    void unscrun(unsigned long *, unsigned char *); 
    void desfunc(unsigned long *, unsigned long *);

private:
    static unsigned char Df_Key[24];
    static unsigned short bytebit[8];
    static unsigned long bigbyte[24];
    static unsigned char pc1[56];
    static unsigned char totrot[16];
    static unsigned char pc2[48];
    static unsigned long SP1[64];
    static unsigned long SP2[64];
    static unsigned long SP3[64];
    static unsigned long SP4[64];
    static unsigned long SP5[64];
    static unsigned long SP6[64];
    static unsigned long SP7[64];
    static unsigned long SP8[64];
};
#endif

而后,具体实现DES类:

//des.cpp

#include <string.h>
#include "Sinodes.h"

int DES::encrypt ( unsigned char key[8], unsigned char* data, int blocks ) 


{
  if ((!data)||(blocks<1))
      return 0;
  deskey ( key, ENCRYPT );
  des ( data, data, blocks);
  return 1;
};

int DES::decrypt ( unsigned char key[8], unsigned char* data, int blocks )
{
  if ((!data)||(blocks<1))
      return 0;
  deskey ( key, DECRYPT );
  des ( data, data, blocks);
  return 1;
};

int DES::yencrypt ( unsigned char key[8], unsigned char* data, int size )
{
  if ((!data)||(size<1))
    return 0;

  // The last char of data is bitwise complemented and filled the rest
  // buffer.If size is 16, it will extend to 24,and 17 still 24.
  char lastChar = *(data+size-1);
  int blocks = size/8+1;
  memset(data+size, ~lastChar, blocks*8-size);
  deskey( key, ENCRYPT );
  return encrypt ( data, data, blocks); 

};

int DES::ydecrypt ( unsigned char key[8], unsigned char* data, int blocks, int* size )
{
  if ( (!data) || (blocks<1) )
    return 0;

  deskey ( key, DECRYPT );
  if ( !decrypt ( data, data, blocks) )
    return 0;
  if ( size != 0 )
  {
    int pos = blocks*8-1;
    char endChar = data[pos];
    while ((pos>0)&&(data[pos]==endChar))
        pos--;
    if ( data[pos] != ~endChar )
      return 0;
    *size = pos+1;
  }
  return 1;
};

// -----------------------------------------------------------------------
// des
//     Encrpts/Decrypts(according to the key currently loaded int the
//     internal key register) SOME blocks of eight bytes at address 'in' 
软件开发网 www.mscto.com


//     into the block at address 'out'. They can be the same.
//
//     "in"
//     "out"
//     "block" Number of blocks.
// -----------------------------------------------------------------------
void DES::des ( unsigned char* in, unsigned char* out, int blocks )
{
for (int i = 0; i < blocks; i++,in+=8,out+=8)
    des_block(in,out);
};

// -----------------------------------------------------------------------
// des_block
//     Encrpts/Decrypts(according to the key currently loaded int the
//     internal key register) one block of eight bytes at address 'in'
//     into the block at address 'out'. They can be the same.
//
//     "in"
//     "out"
// ----------------------------------------------------------------------- 
void DES::des_block(unsigned char *in, unsigned char *out)
{
unsigned long work[2];

scrunch(in, work);
desfunc(work, KnL);
unscrun(work, out);
};

// ----------------------------------------------------------------------
// deskey
//     Sets the internal key register (KnR) according to the hexadecimal
//     key contained in the 8 bytes of hexkey, according to the DES,
//     for encryption or decrytion according to MODE
//
//     "key" is the 64 bits key.
//     "md" means encryption or decryption.
// ----------------------------------------------------------------------
void DES::deskey(unsigned char key[8], Mode md)
{
register int ii, j, l, m, n;
unsigned char pc1m[56], pcr[56];
unsigned long kn[32];

for (j = 0; j < 56; j++) {
  l = pc1[j];
  m = l & 07; 

  pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1:0;
}
for (ii = 0; ii < 16; ii++) {
  if (md == DECRYP) m = (15 - ii) << 1;
    else m = ii << 1;
    n = m + 1;
    kn[m] = kn[n] = 0L;
    for (j = 0; j < 28; j++) {
    l = j + totrot[ii];
    if (l < 28) pcr[j] = pc1m[l];
      else pcr[j] = pc1m[l - 28];
    }
    for (j = 28; j < 56; j++) {
    l = j + totrot[ii];
    if (l < 56) pcr[j] = pc1m[l];
      else pcr[j] = pc1m[l - 28];
    }
    for (j = 0; j < 24; j++) {
    if (pcr[ pc2[j] ]) kn[m] |= bigbyte[j];
    if (pcr[ pc2[j+24] ]) kn[n] |= bigbyte[j];
    }
}
cookey(kn);
return; 


};

// ----------------------------------------------------------------------
// cookey
//     Only called by deskey.
// -----------------------------------------------------------------------
void DES::cookey(register unsigned long *raw1)
{
register unsigned long *cook, *raw0;
unsigned long dough[32];
register int i;

cook = dough;
for (i = 0; i < 16; i++, raw1++) {
  raw0 = raw1++;
  *cook = (*raw0 & 0x00fc0000L) << 6;
  *cook |= (*raw0 & 0x00000fc0L) << 10;
  *cook |= (*raw1 & 0x00fc0000L) >> 10;
  *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
  *cook = (*raw0 & 0x0003f000L) << 12;
  *cook |= (*raw0 & 0x0000003fL) << 16;
  *cook |= (*raw1 & 0x0003f000L) >> 4;
  *cook++ |= (*raw1 & 0x0000003fL);
}
usekey(dough);
return;
};

// ---------------------------------------------------------------------- 

// usekey
//     Only called by cookey.
//     Loads the interal key register with the data in cookedkey.
// -----------------------------------------------------------------------
void DES::usekey(register unsigned long *from)
{
register unsigned long *to, *endp;

to = KnL, endp = &KnL[32];
while (to < endp) *to++ = *from++;
return;
};

void DES::scrunch(register unsigned char *outof, register unsigned long *into )
{
*into = (*outof++ & 0xffL) << 24;
*into |= (*outof++ & 0xffL) << 16;
*into |= (*outof++ & 0xffL) << 8;
*into++ |= (*outof++ & 0xffL);
*into = (*outof++ & 0xffL) << 24;
*into |= (*outof++ & 0xffL) << 16;
*into |= (*outof++ & 0xffL) << 8;
*into |= (*outof & 0xffL);
return;
};

void DES::unscrun(register unsigned long *outof, register unsigned char *into) 
{
*into++ = (*outof >> 24) & 0xffL;
*into++ = (*outof >> 16) & 0xffL;
*into++ = (*outof >> 8) & 0xffL;
*into++ = *outof++ & 0xffL;
*into++ = (*outof >> 24) & 0xffL;
*into++ = (*outof >> 16) & 0xffL;
*into++ = (*outof >> 8) & 0xffL;
*into = *outof & 0xffL;
return;
};

void DES::desfunc(register unsigned long *block,register unsigned long *keys)
{
register unsigned long fval, work, right, leftt;
register int round;

leftt = block[0];
right = block[1];
work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
right ^= work;
leftt ^= (work << 4);
work = ((leftt >> 16) ^ right) & 0x0000ffffL;
right ^= work;
leftt ^= (work << 16);
work = ((right >> 2) ^ leftt) & 0x33333333L;
leftt ^= work;
right ^= (work << 2);
work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
leftt ^= work; 
right ^= (work << 8);
right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
work = (leftt ^ right) & 0xaaaaaaaaL;
leftt ^= work;
right ^= work;
leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;

for (round = 0; round < 8; round++) {
    work = (right << 28) | (right >> 4);
    work ^= *keys++;
    fval = SP7[work       & 0x3fL];
    fval |= SP5[(work >> 8) & 0x3fL];
    fval |= SP3[(work >> 16) & 0x3fL];
    fval |= SP1[(work >> 24) & 0x3fL];
    work = right ^ *keys++;
    fval |= SP8[work       & 0x3fL];
    fval |= SP6[(work >> 8) & 0x3fL];
    fval |= SP4[(work >> 16) & 0x3fL]; 


    fval |= SP2[(work >> 24) & 0x3fL];
    leftt ^= fval;
    work = (leftt << 28) | (leftt >> 4);
    work ^= *keys++;
    fval = SP7[work       & 0x3fL];
    fval |= SP5[(work >> 8) & 0x3fL];
    fval |= SP3[(work >> 16) & 0x3fL];
    fval |= SP1[(work >> 24) & 0x3fL];
    work = leftt ^ *keys++;
    fval |= SP8[work       & 0x3fL];
    fval |= SP6[(work >> 8) & 0x3fL];
    fval |= SP4[(work >> 16) & 0x3fL];
  fval |= SP2[(work >> 24) & 0x3fL];
  right ^= fval;
}
right = (right << 31) | (right >> 1);
work = (leftt ^ right) & 0xaaaaaaaaL;
leftt ^= work;
right ^= work; 
leftt = (leftt << 31) | ( leftt >> 1);
work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
right ^= work;
leftt ^= (work << 8);
work = ((leftt >> 2) ^ right) & 0x33333333L;
right ^= work;
leftt ^= (work << 2);
work = ((right >> 16) ^ leftt) & 0x0000ffffL;
leftt ^= work;
right ^= (work << 16);
work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
leftt ^= work;
right ^= (work << 4);
*block++ = right;
*block = leftt;
return;
};
// -----------------------------------------------------------------------
// Initial of static data members. These data will be used by all the
// instances of class,and can not be changed.
// -----------------------------------------------------------------------
unsigned char DES::Df_Key[24] = {
    0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
    0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 


    0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 };

unsigned short DES::bytebit[8] = {
    0200, 0100, 040, 020, 010, 04, 02, 01 };

unsigned long DES::bigbyte[24] = {
    0x800000L, 0x400000L, 0x200000L, 0x100000L,
    0x80000L, 0x40000L, 0x20000L, 0x10000L,
    0x8000L,   0x4000L,   0x2000L,   0x1000L,
    0x800L,   0x400L,   0x200L,   0x100L,
    0x80L,   0x40L,   0x20L,   0x10L,
    0x8L,     0x4L,     0x2L,     0x1L     };

unsigned char DES::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, 
软件开发网 www.mscto.com


    13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3   };

unsigned char DES::totrot[16] = {
    1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };

unsigned char DES::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   };
unsigned long DES::SP1[64] = {
    0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
    0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
    0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
    0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
    0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, 
    0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
    0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
    0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
    0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
    0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
    0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
    0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
    0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
    0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
    0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
    0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };

unsigned long DES::SP2[64] = {
    0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
    0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, 


    0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
    0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
    0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
    0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
    0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
    0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
    0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
    0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
    0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
    0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
    0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
    0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
    0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
    0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; 



unsigned long DES::SP3[64] = {
    0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
    0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
    0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
    0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
    0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
    0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
    0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
    0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
    0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
    0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
    0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
    0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
    0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, 
    0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
    0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
    0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };

unsigned long DES::SP4[64] = {
    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
    0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
    0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
    0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
    0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
    0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
    0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
    0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
    0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
    0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, 
    0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
    0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
    0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
    0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
    0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };

unsigned long DES::SP5[64] = {
    0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
    0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
    0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
    0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
    0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
    0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
    0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, 软件开发网 www.mscto.com 
    0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
    0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
    0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
    0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
    0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
    0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
    0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
    0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
    0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };

unsigned long DES::SP6[64] = {
    0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
    0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
    0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
    0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, 


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -