文档章节

C语言:ANSI-X9.9-MAC算法实现

ZZ-D-NEMO
 ZZ-D-NEMO
发布于 2017/03/27 21:20
字数 538
阅读 105
收藏 0

示例代码:

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

"mac.c"

/* ANSI-X9.9-MAC算法
 * 将data分为单位8字节的数据块(不足补0x00),分别标号D1-Dn
 * 初始向量E0^D1-->E1(E0与D1异或后DES加密得到E1)
 * E1^D2-->E2
 * 依此类推,得到En,即为MAC

 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>

#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 <buf>\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)

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

验证效果:

【P.S.】说明:

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

© 著作权归作者所有

ZZ-D-NEMO
粉丝 0
博文 5
码字总数 3822
作品 0
顺义
程序员
私信 提问
C语言/C++编程新手学习常见问题

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界
2018/05/11
0
0
c、c++作用域问题&C语言的各种版本:C89,AMD1,C99,C11

突然想到这个问题,循环变量i的作用范围。 标准c语言不能这样定义 编译会失败。 c++中 C语言的各种版本:C89,AMD1,C99,C11 【背景】 之前就知道了有个C90和C99。 后来又在: 【已解决】弄...

mickelfeng
2012/11/04
126
0
小蚂蚁学习C语言(1)——C语言概述

C语言概述 1. 为什么学习C语言 C的起源和发展 1 第一代语言:机器语言 0101 2 第二代语言:汇编语言 add 1,2 3 第三代高级语言: C语言产生和发展过程: 产生时间:1972-1973 产生地点:美国...

嗜学如命的小蚂蚁
2015/11/26
216
4
C语言的起源

文章作者:Tyan 博客:noahsnail.com | CSDN | 简书 C语言是贝尔实验室的Dennis Ritchie于1969年~1973年间创建的。美国国家标准学会(American national standards institute,ANSI)在1989年...

Quincuntial
2017/06/03
0
0
C语言的发展历史:C语言特点,C语言利于弊,入门须知三招

20世纪70年代初,贝尔实验室的Dennis Richie 等人在B语言基础上开发出C语言,最初是作为UNIX的开发语言; 20世纪70年代末,随着微型计算机的发展,C语言开始移植到非UNIX环境中,并逐步成为独...

小辰GG
2017/11/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

iOS Xcode升级包地址(感谢大神)

下载地址:DeviceSupport

_____1____
10分钟前
4
0
Qt编写自定义控件71-圆弧进度条

一、前言 现在web形式的图表框架非常流行,国产代表就是echart,本人用过几次,三个字屌爆了来形容,非常强大,而且易用性也非常棒,还是开源免费的,使用起来不要太爽,内置的各种图表和仪表...

飞扬青云
10分钟前
3
0
润乾报表与 ActiveReport JS 功能对比

简介 润乾报表是用于报表制作的大型企业级报表软件,核心特点在于开创性地提出了非线性报表数学模型,采用了革命性的多源关联分片、不规则分组、自由格间运算、行列对称等技术,使得复杂报表...

泡泡糖儿
22分钟前
4
0
【1015】LNMP架构二

【1015】LNMP架构二 三、PHP安装 PHP安装和LAMP安装PHP方法有差别,需要开启php-fpm服务 1、下载PHP7至/usr/local/src/ 切换目录:cd /usr/local/src 2、解压缩 tar -jxvf php-7.3.0.tar.gz...

飞翔的竹蜻蜓
56分钟前
5
0
浅谈Visitor访问者模式

一、前言 什么叫访问,如果大家学过数据结构,对于这点就很清晰了,遍历就是访问的一般形式,单独读取一个元素进行相应的处理也叫作访问,读取到想要查看的内容+对其进行处理就叫作访问,那么...

青衣霓裳
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部