我给你一个3DES加解密的程序,代码如下: unsigned short WINAPI 3DES_Encrypt( char *svHex, char *svKey, short ivMode, char *srHex ) { int i, ptr, len; unsigned char seed2[8], des_data[8], key_buf[8]; if( !checkhexstr( svHex ) || !checkhexstr(svKey)) return CER_HEXSTR; if( ivMode != ECB && ivMode != CBC) return CER_MODE; // mode only is 0 or 1
len = strlen( svKey ) / 2; if( len != 16 ) return CER_KEYLEN; // len of KEY must be 16 bytes len = strlen( svHex ) / 2; if( len % 8 != 0 ) return CER_DATALEN; // len of DATA must be the time of 8
if( ivMode == CBC && len<16 ) // len of DATA must be larger than 8 return CER_CBC; // Init seed if( ivMode == ICC_CBC ) { for(i=0; i<8; i++) seed2[i] = getbyte(svHex, i+1); ptr = 8; len = len - 8; } else ptr = 0;
解密程序如下: unsigned short WINAPI icc_3DES_Decrypt( char *svHex, char *svKey, short ivMode, char *srHex ) { int i, ptr, len; unsigned char seed2[8], des_data[8], key_buf[8]; if( !checkhexstr( svHex ) || !checkhexstr(svKey)) return CER_HEXSTR; if( ivMode != ECB && ivMode != CBC) return CER_MODE; // mode only is 0 or 1
len = strlen( svKey ) / 2; if( len != 16 ) return CER_KEYLEN; // len of KEY must be 16 bytes len = strlen( svHex ) / 2; if( len % 8 != 0 ) return CER_DATALEN; // len of DATA must be the time of 8
if( ivMode == ICC_CBC && len<16 ) // len of DATA must be larger than 8 return CER_CBC; // Init seed if( ivMode == CBC ) { for(i=0; i<8; i++) seed2[i] = getbyte(svHex, i+1); ptr = 8; len = len - 8; } else ptr = 0;
unsigned short WINAPI 3DES_Encrypt( char *svHex, char *svKey, short ivMode, char *srHex )
{
int i, ptr, len;
unsigned char seed2[8], des_data[8], key_buf[8]; if( !checkhexstr( svHex ) || !checkhexstr(svKey))
return CER_HEXSTR; if( ivMode != ECB && ivMode != CBC)
return CER_MODE; // mode only is 0 or 1
len = strlen( svKey ) / 2;
if( len != 16 )
return CER_KEYLEN; // len of KEY must be 16 bytes len = strlen( svHex ) / 2;
if( len % 8 != 0 )
return CER_DATALEN; // len of DATA must be the time of 8
if( ivMode == CBC && len<16 ) // len of DATA must be larger than 8
return CER_CBC; // Init seed
if( ivMode == ICC_CBC )
{
for(i=0; i<8; i++)
seed2[i] = getbyte(svHex, i+1);
ptr = 8;
len = len - 8;
}
else
ptr = 0;
srHex[0] = '\0';
while( len/8 != 0 )
{
//get plain data
//memcpy(des_data, idata+ptr, 8);
for(i=ptr; i<ptr+8; i++)
des_data[i-ptr] = getbyte( svHex, i+1);
if( ivMode ==CBC )
{
for(i=0;i<8;i++)
des_data[i] = des_data[i] ^ seed2[i];
}
//call the desenciph to encipher
for(i=0; i<8; i++) // DES+
key_buf[i] = getbyte( svKey, i+1);
desenciph(des_data, key_buf); for(i=8; i<16; i++) // DES-
key_buf[i-8] = getbyte( svKey, i+1);
desdeciph(des_data, key_buf);
for(i=0; i<8; i++) // DES+
key_buf[i] = getbyte( svKey, i+1);
desenciph(des_data, key_buf);
if( ivMode == ICC_CBC )
memcpy(seed2, des_data, 8); //get result
for(i=0; i<8; i++)
byte2str( srHex, des_data[i]);
len = len - 8;
ptr = ptr + 8;
}
return EXE_SUC;
}
其中#define ECB 0
#define CBC 1
bool checkhexstr( char *str )
{
int i, len; len = strlen( str );
if( len%2 != 0 )
return false; for( i=0; i<len; i++)
{
if( (str[i]<48 || str[i]>57) // 0...9
&& (str[i]<65 || str[i]>70) // A...F
&& (str[i]<97 || str[i]>102) ) // a...f
return false;
} return true;
}
int getbyte( char *svHex, short num )
{
char stds[] = "0123456789ABCDEF";
char c[2];
int a, b; if( (unsigned int)num > strlen(svHex)/2)
return 0; c[0] = toupper(svHex[2*num-2]);
c[1] = '\0';
a = strcspn( stds, c );
c[0] = toupper(svHex[2*num-1]);
c[1] = '\0';
b = strcspn( stds, c );
return (a*16+b);
}
void desenciph(unsigned char *data, unsigned char *key)
{
unsigned char l[4];
unsigned char r[4];
unsigned char proc[4];
unsigned char key_level[16][8];
int i=1;
//inital permutation
ini_permutation(data);
//key generation
key_gen(key, key_level);
//create right and left units
memcpy(l, data, 4);
memcpy(r, data+4, 4);
memcpy(proc, r, 4);
//begin to encipher
for(i=0;i<16;i++){
f_rk(proc, key_level[i]); //call the function F
lf_xor(l, proc); //Xor the left and and P(B)
if(i==15) break; //end when loop 16
//create the left and right units in the next loop
memcpy(proc, l, 4);
memcpy(l, r, 4);
memcpy(r, proc, 4);
}
//Call the lp-1
memcpy(data, l, 4);
memcpy(data+4, r, 4);
lst_permutation(data);}
void lst_permutation (unsigned char *s)
{
unsigned char p[8];
unsigned char q[8];
unsigned char buf;
unsigned char rule = 1;
int i,j; //begin the last permutation (LP-1)
q[0] = s[3];
q[1] = s[7];
q[2] = s[2];
q[3] = s[6];
q[4] = s[1];
q[5] = s[5];
q[6] = s[0];
q[7] = s[4]; for(i=0;i<8;i++){
p[i] = 0;
for(j=7;j>=0;j--){
buf = q[j];
q[j] = q[j] >> 1;
buf = buf & rule;
p[i] = p[i] | buf;
if(j==0) break;
p[i] = p[i] << 1;
}
} for(i=0;i<8;i++)
s[i] = p[i]; return;
}
unsigned short WINAPI icc_3DES_Decrypt( char *svHex, char *svKey, short ivMode, char *srHex )
{
int i, ptr, len;
unsigned char seed2[8], des_data[8], key_buf[8]; if( !checkhexstr( svHex ) || !checkhexstr(svKey))
return CER_HEXSTR; if( ivMode != ECB && ivMode != CBC)
return CER_MODE; // mode only is 0 or 1
len = strlen( svKey ) / 2;
if( len != 16 )
return CER_KEYLEN; // len of KEY must be 16 bytes len = strlen( svHex ) / 2;
if( len % 8 != 0 )
return CER_DATALEN; // len of DATA must be the time of 8
if( ivMode == ICC_CBC && len<16 ) // len of DATA must be larger than 8
return CER_CBC; // Init seed
if( ivMode == CBC )
{
for(i=0; i<8; i++)
seed2[i] = getbyte(svHex, i+1);
ptr = 8;
len = len - 8;
}
else
ptr = 0;
srHex[0] = '\0';
while( len/8 != 0 )
{
//decipher
//memcpy(des_data, idata+ptr, 8);
for(i=ptr; i<ptr+8; i++)
des_data[i-ptr] = getbyte( svHex, i+1);
//call the desdeciph to decipher
for(i=0; i<8; i++) // DES-
key_buf[i] = getbyte( svKey, i+1);
desdeciph(des_data, key_buf); for(i=8; i<16; i++) // DES+
key_buf[i-8] = getbyte( svKey, i+1);
desenciph(des_data, key_buf); for(i=0; i<8; i++) // DES-
key_buf[i] = getbyte( svKey, i+1);
desdeciph(des_data, key_buf);
if( ivMode == ICC_CBC )
{
for(i=0;i<8;i++)
des_data[i] = des_data[i] ^ seed2[i]; // memcpy(seed2, idata+ptr, 8);
for(i=ptr; i<ptr+8; i++)
seed2[i-ptr] = getbyte( svHex, i+1); }
// memcpy(odata+ptr, des_data, 8);
for(i=0; i<8; i++)
byte2str( srHex, des_data[i]);
len = len - 8;
ptr = ptr + 8;
} return EXE_SUC;
}