📄 h_des.cpp
字号:
//----------------------------------------------------------------------------------------//
// H_Des.cpp : Math Function(Des() e.g) for inner user
// not extern for outside user
//
// Data: 2006.5.15
// Edited by Fenglei
//
//----------------------------------------------------------------------------------------//
#include "stdafx.h"
#include "H_Func.h"
#include "H_Des.h"
//----------------------------------------------------------------------------------------
#define SINGLE 8
#define DOUBLE 16
//----------------------------------------------------------------------------------------
static void SetKey(const IN BYTE *key);
static void Permute(BYTE *inblock, char perm[16][16][8], BYTE *outblock);
static void Round(int num, DWORD *block);
static long F_DES(DWORD r, BYTE subKey[8]);
static void PermInit(char perm[16][16][8], const char p[64]);
static void SPInit(void);
static DWORD ByteSwap(DWORD x);
/************************************************************************
* Tables defined in the Data Encryption Standard documents *
* MAC_DES原始函数组 *
************************************************************************/
/////////////////////////////////////////////////////////////////////////
//
static const char ip[] = /* Initial permutation IP */
{
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
}; /* ip[] */
/////////////////////////////////////////////////////////////////////////
static const char fp[] = /* Final permutation IP^-1 */
{
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
}; /* fp[] */
/////////////////////////////////////////////////////////////////////////
/*
Expansion operation matrix
This is for reference only; it is unused in the code
as the F() function performs it implicitly for speed
*/
#ifdef notdef
static const char ei[] =
{
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
};
#endif /* notdef */
/////////////////////////////////////////////////////////////////////////
static const char pc1[] = /* Permuted choice table (key) */
{
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
};
/////////////////////////////////////////////////////////////////////////
static const char totRot[] = /* Number left rotations of pc1 */
{
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
}; /* totRot[] */
/////////////////////////////////////////////////////////////////////////
static const char pc2[] = /* Permuted choice key (table) */
{
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
}; /* pc2[] */
/////////////////////////////////////////////////////////////////////////
static const char si[8][64] = /* The (in)famous S-boxes */
{
/* 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
}; /* si[] */
/////////////////////////////////////////////////////////////////////////
/* 32-bit permutation function P used on the output of the S-boxes */
static const char p32i[] =
{
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
}; /* p32i[] */
/************************************************************************
* End of DES-defined tables *
************************************************************************/
/////////////////////////////////////////////////////////////////////////
static long sp[8][64]; /* Combined S and P boxes */
static char iperm[16][16][8]; /* Initial and final permutations */
static char fperm[16][16][8];
static int desInited = 0;
/* 8 6-bit subkeys for each of 16 rounds, initialized by SetKey() */
static BYTE kn[16][8];
/* bit 0 is left-most in byte */
static const int byteBit[] =
{
0200, 0100, 040, 020, 010, 04, 02, 01
}; /* byteBit[] */
static const int nibbleBit[] =
{
010, 004, 002, 001
}; /* nibbleBit[] */
/////////////////////////////////////////////////////////////////////////
// DES
//
LPCSTR DES(LPCSTR IN psData, LPCSTR IN psKey, BOOL IN bEncrypt)
{
int iMsgLen= 0, iKeyLen= 0, i;
BYTE bMsg[1024+ 8], bKey[16], b3DES[(1024+ 8)* 2+ 1];
char *psResult= NULL;
try
{
// Parameter Checking
iMsgLen= strlen(psData);
iKeyLen= strlen(psKey);
if(!iMsgLen || !iKeyLen) return NULL;
// Initial
memset(bMsg, 0, sizeof(bMsg));
if(!Asc2Bcd((char *)bMsg, (char *)psData, iMsgLen)) return NULL;
memset(bKey, 0, sizeof(bKey));
if(!Asc2Bcd((char *)bKey, (char *)psKey, iKeyLen)) return NULL;
// Filling
iMsgLen= iMsgLen/ 2; iKeyLen= iKeyLen/ 2;
if(iMsgLen% 8)
{
bMsg[iMsgLen++]= 0x80;
for(; iMsgLen% 8 && iMsgLen< 1024+ 8; ) bMsg[iMsgLen++]= 0x00;
}
// Calculate
for(i= 0; i< iMsgLen/ 8; i++)
{
if(iKeyLen== 16)
{
if(bEncrypt) DES_C_DDES(bKey, &bMsg[i* 8], TRUE);
else DES_C_DDES(bKey, &bMsg[i* 8], FALSE);
}
else if(iKeyLen== 8)
{
if(bEncrypt) DES_C_DES(bKey, &bMsg[i* 8], TRUE);
else DES_C_DES(bKey, &bMsg[i* 8], FALSE);
}
}
// Result
memset(b3DES, 0, sizeof(b3DES));
if(!Bcd2Asc((char *)b3DES, (char *)bMsg, iMsgLen)) return NULL;
psResult= (char *)b3DES;
return psResult;
}
catch(...)
{
return NULL;
}
}
/////////////////////////////////////////////////////////////////////////
// MAC (For Standard MAC)
//
LPCSTR MAC(LPCSTR IN psInitValue, LPCSTR IN psData, LPCSTR IN psKey)
{
int iInitValLen= 0, iMsgLen= 0, iKeyLen= 0, i, j;
BYTE bXOR[8], bMsg[1024+ 8], bKey[16], bMAC[4* 2+ 1];
char *pMAC= NULL;
DWORD dwStatus= 0;
try
{
// Parameter Checking
iInitValLen= strlen(psInitValue);
iMsgLen= strlen(psData);
iKeyLen= strlen(psKey);
if(!iInitValLen || !iMsgLen || !iKeyLen) return NULL;
// Initial
memset(bXOR, 0, sizeof(bXOR));
if(!Asc2Bcd((char *)bXOR, (char *)psInitValue, iInitValLen)) return NULL;
memset(bMsg, 0, sizeof(bMsg));
if(!Asc2Bcd((char *)bMsg, (char *)psData, iMsgLen)) return NULL;
memset(bKey, 0, sizeof(bKey));
if(!Asc2Bcd((char *)bKey, (char *)psKey, iKeyLen)) return NULL;
// Filling
iMsgLen= iMsgLen/ 2; iKeyLen= iKeyLen/ 2;
bMsg[iMsgLen++]= 0x80;
if(iMsgLen% 8)
{
for(; iMsgLen% 8 && iMsgLen< 1024+ 8; ) bMsg[iMsgLen++]= 0x00;
}
// Calculate
for(i= 0; i< iMsgLen/ 8; i++)
{
for(j= 0; j< 8; j++) bXOR[j]= bXOR[j]^ bMsg[i* 8+ j];
if(i!= iMsgLen/ 8- 1)
{
DES_C_DES(bKey, bXOR, TRUE);
}
else
{
DES_C_DDES(bKey, bXOR, TRUE);
}
}
// Result
memset(bMAC, 0, 4* 2+ 1);
if(!Bcd2Asc((char *)bMAC, (char *)bXOR, 4)) return NULL;
pMAC= (char *)bMAC;
return pMAC;
}
catch(...)
{
return NULL;
}
}
/////////////////////////////////////////////////////////////////////////
// 3des加密解密函数
//
void DES_C_DDES(const BYTE IN *key, BYTE IN_OUT *data, bool IN encrypt)
{
if (encrypt)
{
DES_C_DES(key, data,1);
DES_C_DES(key + SINGLE, data,0);
DES_C_DES(key, data,1);
} /* end of if */
else
{
DES_C_DES(key, data,0);
DES_C_DES(key + SINGLE, data,1);
DES_C_DES(key, data,0);
} /* end of else */
return;
} // DDES()
/////////////////////////////////////////////////////////////////////////
// 单des加密解密函数
//
void DES_C_DES(const BYTE IN *key, BYTE IN_OUT *data, int IN doEncrypt)
{
int i;
DWORD work[2]; /* Working data storage */
long tmp;
if (!desInited)
{
SPInit();
PermInit(iperm, ip);
PermInit(fperm, fp);
desInited = 1;
} /* end of if */
SetKey(key);
/* Initial Permutation */
Permute(data, iperm, (BYTE *)work);
work[0] = ByteSwap(work[0]);
work[1] = ByteSwap(work[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -