银联的8583通信报文,使用的mac算法总结。
void DATE_XOR1(U08 *source, U08 *dest,long size) { int i; for(i=0; i<size; i++) dest[i] ^= source[i]; return; } /* ************************************************************************************************* * 异或 ************************************************************************************************* */ void DataXOR( U08 *source, U08 *dest, U32 size, U08 *out ) { int i; for( i = 0; i < size; i++ ) { out[i] = dest[i] ^ source[i]; } } /******************************************************* * 名称:获取报文MAC值 * 功能:报文MAC算法 * 入口: * *buf ,要计算的数据缓冲区;buf_size,计算数据的长度 * *key ,密钥(8B) * 出口:mac_buf,计算出来的MAC值(8B) ********************************************************/ void UP_Get_MAC( U08 *buf, U32 buf_size, U08 *key, U08 *mac_buf ) { U08 val[8],Abuf[8],str1[8],str2[8]; U08 Bbuf[16]; //中间变量 U08 block[512],mac[8]; U16 x,n; U16 i,j=0; //准备工作 memcpy( block, buf, buf_size ); //将输入数据赋值给临时变量block x = buf_size / 8; //计算有多少个完整的块 n = buf_size % 8; //计算最后一个块有几个字节 if( n != 0 ) //y非0,则在其后补上0x00... { memset( &block[x*8+n], 0x00, 8-n ); x += 1; //将补上的这一块加上去 } //开始运算 memset( val, 0x00, 8 ); for( i = 0; i < x; i++ ) //有多少块循环多少次 { DATE_XOR1(&block[j], val,8); j += 8; //用于取下一块的数据 } sprintf( (char *)Bbuf, "%02X%02X%02X%02X%02X%02X%02X%02X", val[0],val[1],val[2],val[3],val[4],val[5],val[6],val[7]); memcpy( str1, Bbuf, 8 ); memcpy( str2, &Bbuf[8], 8 ); CurCalc_DES_Encrypt(key,str1,mac); DataXOR( mac, str2, 8, Abuf ); CurCalc_DES_Encrypt(key,Abuf,mac); memcpy(Abuf,mac,8); sprintf( (char *)Bbuf, "%02X%02X%02X%02X%02X%02X%02X%02X", Abuf[0],Abuf[1],Abuf[2],Abuf[3],Abuf[4],Abuf[5],Abuf[6],Abuf[7]); memcpy( mac_buf, Bbuf, 8 ); //前8位密钥结果放入mac_buf } /******************************************************* * 名称:获取报文MAC值 * 功能:报文MAC算法 * 入口: * *buf ,要计算的数据缓冲区;buf_size,计算数据的长度 * *key ,密钥(8B) * 出口:mac_buf,计算出来的MAC值(8B) ansi x9.9 MAC算法 ********************************************************/ void Ansi99X_Get_MAC( U08 *buf, U32 buf_size, U08 *key, U08 *mac_buf ) { U08 val[8],xor[8]; U08 block[512]; U16 x,n; U16 i,j=0; //准备工作 memcpy( block, buf, buf_size ); //将输入数据赋值给临时变量block x = buf_size / 8; //计算有多少个完整的块 n = buf_size % 8; //计算最后一个块有几个字节 if( n != 0 ) //y非0,则在其后补上0x00... { memset( &block[x*8+n], 0x00, 8-n ); x += 1; //将补上的这一块加上去 } //开始运算 memset( val, 0x00, 8 ); for( i = 0; i < x; i++ ) //有多少块循环多少次 { DataXOR(val,&block[j], 8,xor); CurCalc_DES_Encrypt(key,xor,val);//DES加密 j += 8; //用于取下一块的数据 } memcpy(mac_buf,val, 8 ); }