mac x99算法 java_C语言:ANSI-X9.9-MAC算法实现

本文介绍了ANSI-X9.9 Message Authentication Code (MAC)算法,并提供了C语言的实现代码。通过将输入数据分块并进行DES_CBC加密,结合异或操作计算MAC值。此外,还给出了一个简单的测试用例和Makefile编译规则。
摘要由CSDN通过智能技术生成

示例代码:

****************************************************************************************

"mac.c"

/* ANSI-X9.9-MAC算法

* 将data分为单位8字节的数据块(不足补0x00),分别标号D1-Dn

* 初始向量E0^D1-->E1(E0与D1异或后DES加密得到E1)

* E1^D2-->E2

* 依此类推,得到En,即为MAC

*/

#include

#include

#include

#include

#include

#define CHECK( func ) {             \

if( EXIT_FAILURE == (func) ){   \

exit( EXIT_FAILURE );       \

}                               \

}

/* DES_CBC加密 */

static int encryptDes( unsigned char *key, unsigned char *plain,

unsigned char *cipher, int plen )

{

int clen = 0;

int tmplen = 0;

EVP_CIPHER_CTX ctx;

/* 01:加密初始化

* 使用DES_CBC算法加密 */

EVP_EncryptInit( &ctx, EVP_des_cbc(), key, NULL );

/* 设置不填充(缺省填充) */

if( 0 == plen % 8 ){

EVP_CIPHER_CTX_set_padding( &ctx, 0 );

}

/* 02:加密 */

if( !EVP_EncryptUpdate( &ctx, cipher, &clen, plain, plen ) ){

ERR_print_errors_fp( stderr );

fprintf( stderr, "EVP_EncryptUpdate error\n" );

return EXIT_FAILURE;

}

/* 03:加密后处理 */

if( !EVP_EncryptFinal( &ctx, cipher + clen, &tmplen ) ){

ERR_print_errors_fp( stderr );

fprintf( stderr, "EVP_EncryptFinal error\n" );

return EXIT_FAILURE;

}

clen += tmplen;

return clen;

}

/* ASCII字符串转十六进制字符串显示 */

static int str2hex( unsigned char *sSrc, unsigned char *sDest, int nSrcLen )

{

int  i, DestLen = 0;

char szTmp[2 + 1];

/* LOOP:针对每1个字符处理 */

for( i = 0; i < nSrcLen; i++ )

{

sprintf( szTmp, "%02X", (unsigned char) sSrc[i] );

memcpy( &sDest[i * 2], szTmp, 2 );

DestLen += 2;

}

return DestLen;

}

/* 异或计算 */

static void xor( unsigned char *in1, unsigned char *in2,

unsigned char *out, int len )

{

while( len-- )

*out++ = *in1++ ^ *in2++;

}

/* ANSI-X9.9-MAC算法 */

static int mac_X9_9( unsigned char *key, unsigned char *iv,

unsigned char *data, unsigned char *mac, int len )

{

int i = 0;

int num = 0;

unsigned char updata[9999 + 1] = {0};

unsigned char ddata[8] = {0};

unsigned char edata[8] = {0};

unsigned char xdata[8] = {0};

/* LOOP:以8字节为单位循环计算 */

memcpy( edata, iv, 8 );

memcpy( updata, data, len );

num = ( len + 7 ) / 8;

for( i = 0; i < num; i++ )

{

/* 确认Di */

memcpy( ddata, updata + i * 8, 8 );

/* 计算异或 */

xor( edata, ddata, xdata, 8 );

/* DES加密 */

CHECK( encryptDes( key, xdata, edata, 8 ) );

}

/* 返回MAC-转换十六进制 */

str2hex( edata, mac, 8 );

return EXIT_SUCCESS;

}

/* 测试程序 */

int main( int argc, char *argv[] )

{

int i = 0;

unsigned char mac[999] = {0};

unsigned char key[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

unsigned char iv[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

if( 1 == argc ){

fprintf( stderr, "Usage: %s \n", argv[0] );

exit( EXIT_FAILURE );

}

printf( "BUF[%s]\n", argv[1] );

CHECK( mac_X9_9( key, iv, argv[1], mac, strlen( argv[1] ) ) );

printf( "MAC[%s]\n", mac );

exit( EXIT_SUCCESS );

}

****************************************************************************************

"Makefile":

#执行文件

bin=imacx99

#目标文件

objects=mac.o

#连接规则

$(bin):$(objects)

gcc -o ~/bin/$(bin) $(objects) -lssl -lcrypto -ldl

#清理对象

.PHONY:clean

clean:

-rm ~/bin/$(bin) $(objects)

****************************************************************************************

验证效果:

436d4ed672f7d8469d01c52bc1b6e82a.png

0e3a5e4dbd0e64187128e37b8c4e0ce6.png

【P.S.】说明:

以上截图中用于校验的“DES算法工具”可以网上搜索下载到;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值