根据PBOC规定的加密加MAC算法写出,编程语言为C++
目录结构为:
ReadMe.txt内容:
========================================================================
动态链接库:LB_DES 项目概述
========================================================================
应用程序向导已为您创建了此 LB_DES DLL。
本文件概要介绍组成 LB_DES 应用程序的
的每个文件的内容。
LB_DES.vcproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件,
其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
LB_DES.cpp
这是主 DLL 源文件。
此 DLL 在创建时不导出任何符号。因此,在生成此 DLL 时
将不会产生 .lib 文件。如果希望此项目
成为其他某个项目的项目依赖项,则需要
添加代码以从 DLL 导出某些符号,
以便产生一个导出库,或者,也可以在项目“属性页”对话框中的
“链接器”文件夹中,将“常规”属性页上的
“忽略输入库”属性设置为“是”。
/
其他标准文件:
StdAfx.h, StdAfx.cpp
这些文件用于生成名为 LB_DES.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
/
其他注释:
应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
/
下面发布每一个文件代码
#include "stdafx.h"
#include "des.h"
/*----------------------------------------------------*/
/* 字节拓展成位 */
/*----------------------------------------------------*/
unsigned char *byte2bit(unsigned char byte[64] , unsigned char bit[8])
{
int i = 0;
/*byte1*/
for(i = 0;i <= 7;i++)
{
if(byte[0] == 0x1) bit[0] = bit[0] | 0x80;
else bit[0] = bit[0] & 0x7f;
if(byte[1] == 0x1) bit[0] = bit[0] | 0x40;
else bit[0] = bit[0] & 0xbf;
if(byte[2] == 0x1) bit[0] = bit[0] | 0x20;
else bit[0] = bit[0] & 0xdf;
if(byte[3] == 0x1) bit[0] = bit[0] | 0x10;
else bit[0] = bit[0] & 0xef;
if(byte[4] == 0x1) bit[0] = bit[0] | 0x08;
else bit[0] = bit[0] & 0xf7;
if(byte[5] == 0x1) bit[0] = bit[0] | 0x04;
else bit[0] = bit[0] & 0xfb;
if(byte[6] == 0x1) bit[0] = bit[0] | 0x02;
else bit[0] = bit[0] & 0xfd;
if(byte[7] == 0x1) bit[0] = bit[0] | 0x01;
else bit[0] = bit[0] & 0xfe;
}
/*byte2*/
for(i = 8;i <= 15;i++)
{
if(byte[8] == 0x1) bit[1] = bit[1] | 0x80;
else bit[1] = bit[1] & 0x7f;
if(byte[9] == 0x1) bit[1] = bit[1] | 0x40;
else bit[1] = bit[1] & 0xbf;
if(byte[10] == 0x1) bit[1] = bit[1] | 0x20;
else bit[1] = bit[1] & 0xdf;
if(byte[11] == 0x1) bit[1] = bit[1] | 0x10;
else bit[1] = bit[1] & 0xef;
if(byte[12] == 0x1) bit[1] = bit[1] | 0x08;
else bit[1] = bit[1] & 0xf7;
if(byte[13] == 0x1) bit[1] = bit[1] | 0x04;
else bit[1] = bit[1] & 0xfb;
if(byte[14] == 0x1) bit[1] = bit[1] | 0x02;
else bit[1] = bit[1] & 0xfd;
if(byte[15] == 0x1) bit[1] = bit[1] | 0x01;
else bit[1] = bit[1] & 0xfe;
}
/*byte3*/
for(i = 16;i <= 23;i++)
{
if(byte[16] == 0x1) bit[2] = bit[2] | 0x80;
else bit[2] = bit[2] & 0x7f;
if(byte[17] == 0x1) bit[2] = bit[2] | 0x40;
else bit[2] = bit[2] & 0xbf;
if(byte[18] == 0x1) bit[2] = bit[2] | 0x20;
else bit[2] = bit[2] & 0xdf;
if(byte[19] == 0x1) bit[2] = bit[2] | 0x10;
else bit[2] = bit[2] & 0xef;
if(byte[20] == 0x1) bit[2] = bit[2] | 0x08;
else bit[2] = bit[2] & 0xf7;
if(byte[21] == 0x1) bit[2] = bit[2] | 0x04;
else bit[2] = bit[2] & 0xfb;
if(byte[22] == 0x1) bit[2] = bit[2] | 0x02;
else bit[2] = bit[2] & 0xfd;
if(byte[23] == 0x1) bit[2] = bit[2] | 0x01;
else bit[2] = bit[2] & 0xfe;
}
/*byte4*/
for(i = 24;i <= 31;i++)
{
if(byte[24] == 0x1) bit[3] = bit[3] | 0x80;
else bit[3] = bit[3] & 0x7f;
if(byte[25] == 0x1) bit[3] = bit[3] | 0x40;
else bit[3] = bit[3] & 0xbf;
if(byte[26] == 0x1) bit[3] = bit[3] | 0x20;
else bit[3] = bit[3] & 0xdf;
if(byte[27] == 0x1) bit[3] = bit[3] | 0x10;
else bit[3] = bit[3] & 0xef;
if(byte[28] == 0x1) bit[3] = bit[3] | 0x08;
else bit[3] = bit[3] & 0xf7;
if(byte[29] == 0x1) bit[3] = bit[3] | 0x04;
else bit[3] = bit[3] & 0xfb;
if(byte[30] == 0x1) bit[3] = bit[3] | 0x02;
else bit[3] = bit[3] & 0xfd;
if(byte[31] == 0x1) bit[3] = bit[3] | 0x01;
else bit[3] = bit[3] & 0xfe;
}
/*byte5*/
for(i = 32;i <= 39;i++)
{
if(byte[32] == 0x1) bit[4] = bit[4] | 0x80;
else bit[4] = bit[4] & 0x7f;
if(byte[33] == 0x1) bit[4] = bit[4] | 0x40;
else bit[4] = bit[4] & 0xbf;
if(byte[34] == 0x1) bit[4] = bit[4] | 0x20;
else bit[4] = bit[4] & 0xdf;
if(byte[35] == 0x1) bit[4] = bit[4] | 0x10;
else bit[4] = bit[4] & 0xef;
if(byte[36] == 0x1) bit[4] = bit[4] | 0x08;
else bit[4] = bit[4] & 0xf7;
if(byte[37] == 0x1) bit[4] = bit[4] | 0x04;
else bit[4] = bit[4] & 0xfb;
if(byte[38] == 0x1) bit[4] = bit[4] | 0x02;
else bit[4] = bit[4] & 0xfd;
if(byte[39] == 0x1) bit[4] = bit[4] | 0x01;
else bit[4] = bit[4] & 0xfe;
}
/*byte6*/
for(i = 40;i <= 47;i++)
{
if(byte[40] == 0x1) bit[5] = bit[5] | 0x80;
else bit[5] = bit[5] & 0x7f;
if(byte[41] == 0x1) bit[5] = bit[5] | 0x40;
else bit[5] = bit[5] & 0xbf;
if(byte[42] == 0x1) bit[5] = bit[5] | 0x20;
else bit[5] = bit[5] & 0xdf;
if(byte[43] == 0x1) bit[5] = bit[5] | 0x10;
else bit[5] = bit[5] & 0xef;
if(byte[44] == 0x1) bit[5] = bit[5] | 0x08;
else bit[5] = bit[5] & 0xf7;
if(byte[45] == 0x1) bit[5] = bit[5] | 0x04;
else bit[5] = bit[5] & 0xfb;
if(byte[46] == 0x1) bit[5] = bit[5] | 0x02;
else bit[5] = bit[5] & 0xfd;
if(byte[47] == 0x1) bit[5] = bit[5] | 0x01;
else bit[5] = bit[5] & 0xfe;
}
/*byte7*/
for(i = 48;i <= 55;i++)
{
if(byte[48] == 0x1) bit[6] = bit[6] | 0x80;
else bit[6] = bit[6] & 0x7f;
if(byte[49] == 0x1) bit[6] = bit[6] | 0x40;
else bit[6] = bit[6] & 0xbf;
if(byte[50] == 0x1) bit[6] = bit[6] | 0x20;
else bit[6] = bit[6] & 0xdf;
if(byte[51] == 0x1) bit[6] = bit[6] | 0x10;
else bit[6] = bit[6] & 0xef;
if(byte[52] == 0x1) bit[6] = bit[6] | 0x08;
else bit[6] = bit[6] & 0xf7;
if(byte[53] == 0x1) bit[6] = bit[6] | 0x04;
else bit[6] = bit[6] & 0xfb;
if(byte[54] == 0x1) bit[6] = bit[6] | 0x02;
else bit[6] = bit[6] & 0xfd;
if(byte[55] == 0x1) bit[6] = bit[6] | 0x01;
else bit[6] = bit[6] & 0xfe;
}
/*byte8*/
for(i = 56;i <= 63;i++)
{
if(byte[56] == 0x1) bit[7] = bit[7] | 0x80;
else bit[7] = bit[7] & 0x7f;
if(byte[57] == 0x1) bit[7] = bit[7] | 0x40;
else bit[7] = bit[7] & 0xbf;
if(byte[58] == 0x1) bit[7] = bit[7] | 0x20;
else bit[7] = bit[7] & 0xdf;
if(byte[59] == 0x1) bit[7] = bit[7] | 0x10;
else bit[7] = bit[7] & 0xef;
if(byte[60] == 0x1) bit[7] = bit[7] | 0x08;
else bit[7] = bit[7] & 0xf7;
if(byte[61] == 0x1) bit[7] = bit[7] | 0x04;
else bit[7] = bit[7] & 0xfb;
if(byte[62] == 0x1) bit[7] = bit[7] | 0x02;
else bit[7] = bit[7] & 0xfd;
if(byte[63] == 0x1) bit[7] = bit[7] | 0x01;
else bit[7] = bit[7] & 0xfe;
}
return bit;
}
/*----------------------------------------------------*/
/* 位压缩成字节 */
/*----------------------------------------------------*/
unsigned char *bit2byte(unsigned char bit[8] , unsigned char byte[64])
{
int i=0;
for(i=0; i<=63; i++)
{
byte[i] = 0x00;
}
for(i=0; i<=7; i++)
{
if((bit[i] & 0x80) == 0x80) byte[i*8+0] = 0x01;
if((bit[i] & 0x40) == 0x40) byte[i*8+1] = 0x01;
if((bit[i] & 0x20) == 0x20) byte[i*8+2] = 0x01;
if((bit[i] & 0x10) == 0x10) byte[i*8+3] = 0x01;
if((bit[i] & 0x08) == 0x08) byte[i*8+4] = 0x01;
if((bit[i] & 0x04) == 0x04) byte[i*8+5] = 0x01;
if((bit[i] & 0x02) == 0x02) byte[i*8+6] = 0x01;
if((bit[i] & 0x01) == 0x01) byte[i*8+7] = 0x01;
}
return byte;
}
/*--------------------------------------------------*/
/* 密钥变换 */
/*--------------------------------------------------*/
void keychange(unsigned char oldkey[8] , unsigned char newkey[16][8])
{
int i=0,j=0,k=0;
int pc_1[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};
int pc_2[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};
int ccmovebit[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
unsigned char oldkey_byte[64];
unsigned char oldkey_byte1[64];
unsigned char oldkey_byte2[64];
unsigned char oldkey_c[28];
unsigned char oldkey_d[28];
unsigned char cc_temp;
unsigned char newkey_byte[16][64];
bit2byte(oldkey,oldkey_byte);
for(i=0;i<=55;i++) oldkey_byte1[i] = oldkey_byte[pc_1[i] - 1];
for(i=0;i<=27;i++) oldkey_c[i] = oldkey_byte1[i];
for(i=28;i<=55;i++) oldkey_d[i -28] = oldkey_byte1[i];
for(i=0;i<=15;i++)
{
for(j=1;j<=ccmovebit[i];j++)
{
cc_temp = oldkey_c[0];
for(k=0;k<=26;k++)
{
oldkey_c[k] = oldkey_c[k+1];
}
oldkey_c[27] = cc_temp;
cc_temp = oldkey_d[0];
for(k=0;k<=26;k++)
{
oldkey_d[k] = oldkey_d[k+1];
}
oldkey_d[27] = cc_temp;
}
for(k=0;k<=27;k++) oldkey_byte2[k] = oldkey_c[k];
for(k=28;k<=55;k++) oldkey_byte2[k] = oldkey_d[k-28];
for(k=0;k<=47;k++) newkey_byte[i][k] = oldkey_byte2[pc_2[k] - 1];
}
for(i=0;i<=15;i++) byte2bit(newkey_byte[i],newkey[i]);
}
/*--------------------------------------------------*/
/* S_replace */
/*--------------------------------------------------*/
void s_replace(unsigned char s_bit[])
{
int p[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
};
unsigned char s1[4][16] = { 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
};
unsigned char s2[4][16] = { 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
};
unsigned char s3[4][16] = { 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
};
unsigned char s4[4][16] = { 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
};
unsigned char s5[4][16] = { 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,
};
unsigned char s6[4][16] = { 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
};
unsigned char s7[4][16] = { 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
};
unsigned char s8[4][16] = { 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
};
int i=0 , j=0;
unsigned char s_byte[64];
unsigned char s_byte1[64];
unsigned char s_bit_temp[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
unsigned char row = 0 , col = 0;
unsigned char s_out_bit[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
unsigned char s_out_bit1[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
/*initialize*/
for(i=0;i<=63;i++) s_byte[i] = 0x0;
for(i=0;i<=63;i++) s_byte1[i] = 0x0;
/*change 48bit(8bit x 6byte) to 48bit(6bit x 8byte)*/
bit2byte(s_bit,s_byte);
for(i=0;i<=7;i++)
{
for(j=0;j<=63;j++) s_byte1[j] = 0x0;/*clear temp*/
s_byte1[6] = s_byte[i*6]; /*get bit 0 in 6 bit*/
s_byte1[7] = s_byte[i*6+5];/*get bit 5 in 6 bit*/
byte2bit(s_byte1,s_bit_temp);/* 0000 00?? */
row = s_bit_temp[0];/*get row[i]*/
for(j=0;j<=63;j++) s_byte1[j] = 0x0;/*clear temp*/
s_byte1[4] = s_byte[i*6+1];/*0000 ????*/
s_byte1[5] = s_byte[i*6+2];
s_byte1[6] = s_byte[i*6+3];
s_byte1[7] = s_byte[i*6+4];
byte2bit(s_byte1,s_bit_temp);
col = s_bit_temp[0];/*get column in S table*/
/*get number from S table with row and col*/
switch (i) {
case 0 :
s_out_bit[i] = s1[row][col];
break;
case 1 :
s_out_bit[i] = s2[row][col];
break;
case 2 :
s_out_bit[i] = s3[row][col];
break;
case 3 :
s_out_bit[i] = s4[row][col];
break;
case 4 :
s_out_bit[i] = s5[row][col];
break;
case 5 :
s_out_bit[i] = s6[row][col];
break;
case 6 :
s_out_bit[i] = s7[row][col];
break;
case 7 :
s_out_bit[i] = s8[row][col];
break;
};
}
s_out_bit1[0] = (s_out_bit[0]<<4) + s_out_bit[1];
s_out_bit1[1] = (s_out_bit[2]<<4) + s_out_bit[3];
s_out_bit1[2] = (s_out_bit[4]<<4) + s_out_bit[5];
s_out_bit1[3] = (s_out_bit[6]<<4) + s_out_bit[7];
for(i=0;i<=63;i++) s_byte[i]=0x0;
for(i=0;i<=63;i++) s_byte1[i]= 0x0;
bit2byte(s_out_bit1 , s_byte);
for(i=0;i<=31;i++) s_byte1[i] = s_byte[p[i] - 1];
for(i=0;i<=7;i++) s_bit[i] = 0x0;
byte2bit(s_byte1 , s_bit);
}
/*--------------------------------------------------*/
/* data encryption */
/*--------------------------------------------------*/
void endes(unsigned char m_bit[8] , unsigned char k_bit[8] , unsigned char e_bit[8])
{
int ip[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
};
int ip_1[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
};
int e[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
};
unsigned char m_bit1[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
unsigned char m_byte[64];
unsigned char m_byte1[64];
unsigned char key_n[16][8];
unsigned char l_bit[17][8];
unsigned char r_bit[17][8];
unsigned char e_byte[64];
unsigned char e_byte1[64];
unsigned char r_byte[64];
unsigned char r_byte1[64];
int i = 0 , j = 0;
/*initialize*/
for(i=0;i<=15;i++)
{
for(j=0;j<=7;j++)
{
l_bit[i][j] = 0x0;
r_bit[i][j] = 0x0;
key_n[i][j] = 0x0;
}
}
for(i=0;i<=63;i++)
{
m_byte[i] = 0x0;
m_byte1[i] = 0x0;
r_byte[i] = 0x0;
r_byte1[i] = 0x0;
e_byte[i] = 0x0;
e_byte1[i] = 0x0;
}
keychange(k_bit,key_n);
bit2byte(m_bit,m_byte);
for(i=0;i<=63;i++) m_byte1[i] = m_byte[ip[i] - 1];
byte2bit(m_byte1,m_bit1);
for(i=0;i<=3;i++) l_bit[0][i] = m_bit1[i];
for(i=4;i<=7;i++) r_bit[0][i - 4] = m_bit1[i];
for(i=1;i<=16;i++)
{
for(j=0;j<=3;j++) l_bit[i][j] = r_bit[i-1][j];
bit2byte(r_bit[i-1],r_byte);
for(j=0;j<=47;j++) r_byte1[j] = r_byte[e[j] - 1];
byte2bit(r_byte1,r_bit[i-1]);
for(j=0;j<=5;j++) r_bit[i-1][j] = r_bit[i-1][j] ^ key_n[i-1][j];
s_replace(r_bit[i-1]);
for(j=0;j<=3;j++)
{
r_bit[i][j] = l_bit[i-1][j] ^ r_bit[i-1][j];
}
}
for(i=0;i<=3;i++) e_bit[i] = r_bit[16][i];
for(i=4;i<=7;i++) e_bit[i] = l_bit[16][i - 4];
bit2byte(e_bit,e_byte);
for(i=0;i<=63;i++) e_byte1[i] = e_byte[ip_1[i] - 1];
byte2bit(e_byte1,e_bit);
}
/*--------------------------------------------------*/
/* data uncryption */
/*--------------------------------------------------*/
void undes(unsigned char m_bit[8] , unsigned char k_bit[8] , unsigned char e_bit[8])
{
/*事实上此时m_bit是待解密的密文,e_bit是解密后的明文*/
int ip[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
};
int ip_1[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
};
int e[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
};
unsigned char m_bit1[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
unsigned char m_byte[64];
unsigned char m_byte1[64];
unsigned char key_n[16][8];
unsigned char l_bit[17][8];
unsigned char r_bit[17][8];
unsigned char e_byte[64];
unsigned char e_byte1[64];
unsigned char l_byte[64];
unsigned char l_byte1[64];
int i = 0 , j = 0;
for(i=0;i<=15;i++)
{
for(j=0;j<=7;j++)
{
l_bit[i][j] = 0x0;
r_bit[i][j] = 0x0;
key_n[i][j] = 0x0;
}
}
for(i=0;i<=63;i++)
{
m_byte[i] = 0x0;
m_byte1[i] = 0x0;
l_byte[i] = 0x0;
l_byte1[i] = 0x0;
e_byte[i] = 0x0;
e_byte1[i] = 0x0;
}
keychange(k_bit,key_n);
bit2byte(m_bit,m_byte);
for(i=0;i<=63;i++) m_byte1[i] = m_byte[ip[i] - 1];
byte2bit(m_byte1,m_bit1);
for(i=0;i<=3;i++) r_bit[16][i] = m_bit1[i];
for(i=4;i<=7;i++) l_bit[16][i - 4] = m_bit1[i];
for(i=16;i>=1;i--)
{
for(j=0;j<=3;j++) r_bit[i-1][j] = l_bit[i][j];
bit2byte(l_bit[i],l_byte);
for(j=0;j<=47;j++) l_byte1[j] = l_byte[e[j] - 1];
byte2bit(l_byte1,l_bit[i]);
for(j=0;j<=5;j++) l_bit[i][j] = l_bit[i][j] ^ key_n[i-1][j];
s_replace(l_bit[i]);
for(j=0;j<=3;j++)
{
l_bit[i-1][j] = r_bit[i][j] ^ l_bit[i][j];
}
}
for(i=0;i<=3;i++) e_bit[i] = l_bit[0][i];
for(i=4;i<=7;i++) e_bit[i] = r_bit[0][i - 4];
bit2byte(e_bit,e_byte);
for(i=0;i<=63;i++) e_byte1[i] = e_byte[ip_1[i] - 1];
byte2bit(e_byte1,e_bit);
}
void en3des(unsigned char m[8],unsigned char k[16],unsigned char e[8])
{
unsigned char uszkeytmp[8];
unsigned char uszetmp[8];
unsigned char uszmtmp[8];
//16字节key左半部分DES加密
memcpy(uszkeytmp,k,8);
endes(m,uszkeytmp,uszetmp);
//16字节key右半部分DES解密
memcpy(uszkeytmp,k+8,8);
undes(uszetmp,uszkeytmp,uszmtmp);
//16字节key左半部分DES加密
memcpy(uszkeytmp,k,8);
endes(uszmtmp,uszkeytmp,uszetmp);
memcpy(e,uszetmp,8);
return;
}
void un3des(unsigned char e[8],unsigned char k[16],unsigned char m[8])
{
unsigned char uszkeytmp[8];
unsigned char uszetmp[8];
unsigned char uszmtmp[8];
//16字节左半部分DES解密
memcpy(uszkeytmp,k,8);
undes(e,uszkeytmp,uszmtmp);
//16字节右半部分des加密
memcpy(uszkeytmp,k+8,8);
endes(uszmtmp,uszkeytmp,uszetmp);
//16字节左半部分des解密
memcpy(uszkeytmp,k,8);
undes(uszetmp,uszkeytmp,uszmtmp);
memcpy(m,uszmtmp,8);
return;
}
/*mac*/
void Mac(unsigned char *data,
unsigned char*k,
unsigned char vec[8],
int datalen,
MACModel macmodel,
unsigned char macvalue[8])
{
switch (macmodel)
{
case ANSI_XNOR_DES:
MACansixnordes(data,k,vec,datalen,macvalue);
break;
case ANSI_XNOR_3DES:
MACansixnor3des(data,k,vec,datalen,macvalue);
break;
case PBOC_XNOR_DES:
MACpbocxnordes(data,k,vec,datalen,macvalue);
break;
case PBOC_XNOR_3DES:
MACpbocxnor3des(data,k,vec,datalen,macvalue);
break;
default:break;
}
return;
}
/*ansi xnor des mac*/
void MACansixnordes(unsigned char *data,
unsigned char k[8],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8])
{
unsigned char* databuff = NULL;
int maclen = datalen;
unsigned char section[8] = {0x00};
unsigned char result[8] = {0x00};
unsigned char tmp[8] = {0x00};
int i = 0, j = 0;
while(maclen % 8 !=0)
{
maclen++;
}
databuff = (unsigned char*)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
/*不足补零*/
if (maclen > datalen)
{
memset(databuff+datalen, 0x00, maclen-datalen);
}
for(i = 0; i < maclen; i += 8)
{
memcpy(section, databuff+i, 8);
if (i == 0)
{
for(j = 0; j < 8; j++)
{
result[j] = vec[j] ^ section[j];
}
}
else
{
endes(result, k, tmp);
for(j = 0; j < 8; j++)
{
result[j] = tmp[j] ^ section[j];
}
}
}
endes(result, k, macvalue);
free(databuff);
return;
}
/*ansi xnor 3des mac*/
void MACansixnor3des(unsigned char *data,
unsigned char k[16],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8])
{
unsigned char* databuff = NULL;
int maclen = datalen;
unsigned char section[8] = {0x00};
unsigned char result[8] = {0x00};
unsigned char tmp[8] = {0x00};
unsigned char kleft[8] = {0x00};
unsigned char kright[8] = {0x00};
/*生成左右密钥*/
memcpy(kleft, k, 8);
memcpy(kright, k+8, 8);
int i = 0, j = 0;
while(maclen % 8 !=0)
{
maclen++;
}
databuff = (unsigned char*)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
/*不足补零*/
if (maclen > datalen)
{
memset(databuff+datalen, 0x00, maclen-datalen);
}
for(i = 0; i < maclen; i += 8)
{
memcpy(section, databuff+i, 8);
if (i == 0)
{
for(j = 0; j < 8; j++)
{
result[j] = vec[j] ^ section[j];
}
}
else
{
endes(result, kleft, tmp);
for(j = 0; j < 8; j++)
{
result[j] = tmp[j] ^ section[j];
}
}
}
en3des(result, k, macvalue);
free(databuff);
return;
}
/*pboc xnor des mac*/
void MACpbocxnordes(unsigned char *data,
unsigned char k[8],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8])
{
unsigned char* databuff = NULL;
int maclen = datalen;
/*PBOC数据补齐*/
if (datalen % 8 == 0)
{
maclen += 8;
databuff = (unsigned char *)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
memcpy(databuff + datalen,"\x80\x00\x00\x00\x00\x00\x00\x00", 8);
}
else
{
maclen +=1;
if (maclen % 8 ==0)
{
databuff = (unsigned char *)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
memset(databuff + datalen, 0x80, 1);
}
else
{
while(maclen % 8!=0)
{
maclen ++;
}
databuff = (unsigned char *)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
memcpy(databuff + datalen, "\x80\x00\x00\x00\x00\x00\x00\x00",\
maclen - datalen);
}
}
/*des计算mac*/
MACansixnordes(databuff, k, vec, maclen, macvalue);
free(databuff);
return;
}
/*pboc xnor 3des mac*/
void MACpbocxnor3des(unsigned char *data,
unsigned char k[16],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8])
{
unsigned char* databuff = NULL;
int maclen = datalen;
/*PBOC数据补齐*/
if (datalen % 8 == 0)
{
maclen += 8;
databuff = (unsigned char *)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
memcpy(databuff + datalen,"\x80\x00\x00\x00\x00\x00\x00\x00", 8);
}
else
{
maclen +=1;
if (maclen % 8 ==0)
{
databuff = (unsigned char *)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
memset(databuff + datalen, 0x80, 1);
}
else
{
while(maclen % 8!=0)
{
maclen ++;
}
databuff = (unsigned char *)malloc(sizeof(unsigned char)*maclen);
memcpy(databuff, data, datalen);
memcpy(databuff + datalen, "\x80\x00\x00\x00\x00\x00\x00\x00",\
maclen - datalen);
}
}
/*3des计算mac*/
MACansixnor3des(databuff, k, vec, maclen, macvalue);
free(databuff);
return;
}
/*Diversify密钥分散*/
void Diversify(unsigned char mk[16],
unsigned char data[8],
unsigned char dk[16]
)
{
unsigned char notdata[8];
int i = 0;
for (i = 0; i < 8;i ++)
{
notdata[i] = ~data[i];
}
en3des(data, mk, dk);
en3des(notdata, mk, dk+8);
}
#include <stdlib.h>
#ifndef __DES_H__
#define __DES_H__
//
//
//加解密模式
enum CryptModel{DES,DES3,OTHER};
//MAC模式
enum MACModel{ANSI_DATAXNOR_DES,ANSI_DATAXNOR_3DES,ANSI_XNOR_DES,ANSI_XNOR_3DES,
PBOC_DATAXNOR_DES,PBOC_DATAXNOR_3DES,PBOC_XNOR_DES,PBOC_XNOR_3DES};
/*des加密算法*/
/*参数:m:8字节明文 k八字节密钥 e八字节密文*/
void endes(unsigned char m[8],unsigned char k[8],unsigned char e[8]);
/*des解密算法*/
/*参数:e:8字节密文 k八字节密钥 m八字节明文*/
void undes(unsigned char e[8],unsigned char k[8],unsigned char m[8]);
/*3des加密算法*/
/*参数:m:8字节明文 k八字节密钥 e八字节密文*/
void en3des(unsigned char m[8],unsigned char k[16],unsigned char e[8]);
/*3des加密算法*/
/*参数:m:8字节明文 k八字节密钥 e八字节密文*/
void un3des(unsigned char e[8],unsigned char k[16],unsigned char m[8]);
/*MAC校验*/
void Mac(unsigned char *data,
unsigned char*k,
unsigned char vec[8],
int datalen,
MACModel macmodel,
unsigned char macvalue[8]);
/*ansi xnor des mac*/
void MACansixnordes(unsigned char *data,
unsigned char k[8],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8]);
/*ansi xnor 3des mac*/
void MACansixnor3des(unsigned char *data,
unsigned char k[16],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8]);
/*pboc xnor des mac*/
void MACpbocxnordes(unsigned char *data,
unsigned char k[8],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8]);
/*pboc xnor 3des mac*/
void MACpbocxnordes(unsigned char *data,
unsigned char k[16],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8]);
/*pboc xnor 3des mac*/
void MACpbocxnor3des(unsigned char *data,
unsigned char k[16],
unsigned char vec[8],
int datalen,
unsigned char macvalue[8]);
/*Diversify密钥分散*/
void Diversify(unsigned char mk[16],
unsigned char data[8],
unsigned char dk[16]
);
#endif
#ifndef __TOOLS_H_
#define __TOOLS_H_
//#define DLL_FILE //调用dll时删除此定义
#ifdef DLL_FILE
#define DLL_PORT _declspec(dllexport)
#else
#define DLL_PORT _declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define FILELINE __FILE__, __LINE__
//写日志文件路径为log目录下
#define LOGDIR "log"
enum E_LOGLEVEL
{
LOG_FILE=1,
LOG_DEBUG
};
//日志文件名
DLL_PORT char sg_szLogName[];
/*
功能: 写文本日志
参数:
char * pszFile 调用的程序名
int iLine 调用的程序的行数
int iLogFlag LOG_MON:写监控屏, LOG_DEBUG:写调试信息 LOG_FILE:写日志文件, LOG_MON_FILE:写监控屏与日志文件
char *pszFormat 流水内容
返回:
*/
void WINAPI WriteLogTxt(char * pszFile, int iLine, int iLogFlag, char *pszFormat, ...);
/*
功能: 写十六进制日志
参数:
char * pszFile 调用的程序名
int iLine 调用的程序的行数
int iLogFlag LOG_MON:写监控屏, LOG_DEBUG:写调试信息 LOG_FILE:写日志文件, LOG_MON_FILE:写监控屏与日志文件
char *pszTitle 标题
unsigned char *puszLog 内容
int iLength 内容长度
返回:
*/
void WINAPI WriteLogHex(char * pszFile, int iLine, int iLogFlag, char *pszTitle, unsigned char *puszLog, int iLength);
void WINAPI asc_to_bcd(unsigned char *bcd_buf, unsigned char *ascii_buf, int conv_len, unsigned char type);
void WINAPI bcd_to_asc(unsigned char *ascii_buf, unsigned char *bcd_buf, int conv_len, unsigned char type);
void WINAPI bcd_to_int(int &value, unsigned char *bcd_buf, int conv_len, unsigned char type);
void WINAPI int_to_bcd(unsigned char *bcd_buf, int value, int conv_len, unsigned char type);
//2字节转换
void WINAPI IntToHex(int in, char* out);
void WINAPI HexToInt(char* in, int &out);
//4字节转换
void WINAPI VInt2Byte(int iInt, char *pByte);
void WINAPI VByte2Int(int &iInt, char *pByte);
//one byte change to two bytes
void WINAPI One2Two(unsigned char *pusFrom, unsigned int uiFromLen, unsigned char *pusTo);
unsigned char WINAPI GetSum(unsigned char* uszMsg, int iLen);
void WINAPI ClearBlank(unsigned char* pMsgIn, int iMsgLen, unsigned char* pMsgOut, int &iLenOut);
int WINAPI Str2Byte(char *pszStr, int iLen, UCHAR &cOut);
int WINAPI Get0xffString(char *src, int srcLen, char *desc, int &descLen, int pos);
void WINAPI LeftAddAsc0(char *pszBuf, int iBufLen);
void WINAPI RightAddSpace(char *pszBuf, int iBufLen);
//获取当前日期/时间
void WINAPI vGetDateTime(char *pszDateTime, int iFlag);
void WINAPI Xor(unsigned char *pusStr1, unsigned char *pusStr2, unsigned int uiNum);
void WINAPI TrimStr(char *pszBuf);
//得到文件名称 如:把D:\20040726\TeleComCli.cpp 转换为 TeleComCli.cpp
void WINAPI VGetFileName(char *pszFileIn, char *pszFileOut);
#ifdef __cplusplus
}
#endif
#endif
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
// Windows 头文件:
#include <windows.h>
// TODO: 在此处引用程序需要的其他头文件
#define MAX_STR 1024
#include "des.h"
#include "tools.h"
#define extc extern "C" // Assure that names are not mangled
#define _export __declspec(dllexport)
#pragma once
// 以下宏定义要求的最低平台。要求的最低平台
// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
// 正常工作。
// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
// 有关不同平台对应值的最新信息,请参考 MSDN。
#ifndef WINVER // 指定要求的最低平台是 Windows Vista。
#define WINVER 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINNT // 指定要求的最低平台是 Windows Vista。
#define _WIN32_WINNT 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINDOWS // 指定要求的最低平台是 Windows 98。
#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
#endif
#ifndef _WIN32_IE // 指定要求的最低平台是 Internet Explorer 7.0。
#define _WIN32_IE 0x0700 // 将此值更改为相应的值,以适用于 IE 的其他版本。
#endif
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// LB_DES.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
// m_macdata 840E000004
// m_mackey FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
// m_vec 526D01BF6D7236A4
// m_macvalue 返回
extc void _export cdecl Get3DesPbocMacCode(char* m_macdata, char* m_mackey, char* m_vec, char* m_macvalue)
{
int datalen = strlen(m_macdata);
unsigned char vec[8] = {0x00};
unsigned char macvalue[8] = {0x00};
unsigned char mackey[16] = {0x00};
unsigned char *macdata = new unsigned char [datalen / 2];
asc_to_bcd(vec, (unsigned char*)(LPCTSTR)m_vec, 16, 0);
asc_to_bcd(mackey, (unsigned char*)(LPCTSTR)m_mackey, 32, 0);
asc_to_bcd(macdata, (unsigned char*)(LPCTSTR)m_macdata, datalen, 0);
Mac(macdata, mackey, vec, datalen / 2, PBOC_XNOR_3DES, macvalue);
unsigned char tmp[MAX_STR]={0x00};
bcd_to_asc((unsigned char*)(LPCTSTR)tmp, macvalue, 16, 0);
strcpy(m_macvalue, (LPCTSTR)tmp);
//printf("mac value code = %s", m_macvalue);
}
// stdafx.cpp : 只包括标准包含文件的源文件
// LB_DES.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用
把以上代码编译成功后会产生DLL文件 ,先用反编译工具查看是否先函数编译成功并且导出,正确导出如图所示:
至此算法函数完成,只要在相关应用中调用即可;
另附加源码包;