银联通信MAC算法

时间:2022-07-22
本文章向大家介绍银联通信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 );
}