1. 简介

MAC是使用命令的所有元素(包括命令头)产生的。一条命令的完整性,包括命令数据域(如果存在的话)中的数据元,通过安全报文传送得以保证。按照如下的方式使用单重或三重DEA加密方式产生MAC:

第一步:取8个字节的16进制数字’0’作为初始变量。

第二步:按照顺序将数据串联在一起形成数据块。

第三步:将该数据块分成8字节为单位的数据块,标号为D1、D2、D3、D4等。最后的数据块有可能是1-8个字节。

第四步:如果最后的数据块长度是8字节的话,则在其后加上16进制数字’80 00 00 00 00 00 00 00’,转到第五步。如果最后的数据块长度不足8字节,则在其后加上16进制数字’80’,如果达到8字节长度,则转入第五步;否则在其后加入16进制数字’0’直到长度达到8字节。

第五步:对这些数据块使用MAC过程密钥进行加密。如果安全报文传送支持单长度的MAC DEA密钥,则依照下图的方式使用MAC 过程密钥来产生MAC。

第六步:最终得到是从计算结果左侧取得的4字节长度的MAC。

2. 源码实现:

void DoSSMac(const BYTE* input, intnInLen, const BYTE* key, int nKeyLen, BYTE* output)
{
BYTE byInitVec[8]; //初始向量
BYTE byTemp[8]; memset(byInitVec, 0x00,sizeof(byInitVec));
memset(byTemp, 0x00,sizeof(byTemp)); memcpy(byInitVec, input, 8); BYTEbySubKey[3][16][48]; //秘钥 memset(bySubKey, 0x01, sizeof(bySubKey)); int i = 0;
int j = (nInLen >> 3); //构造并生成SubKeys
BYTE nKey = (nKeyLen >> 3) > 3 ?3 : (nKeyLen >> 3);
for (i = 0; i < nKey; i++)
{
SetSubKey(&bySubKey[i], &key[i << 3]);
} memcpy(output, input, 8);
if (1 == nKey) //单倍长Key(8字节)
{
j--;
for (int i = 0; i <j; ++i)
{
Xor(input + 8 * (i + 1), output, 8, output);
RunDes(output, 0, &bySubKey[0], output); //memcpy(byInitVec, output, 8); //将输出设定为扭转变量
}
}
<span style="color:#ff0000;"> //转换关系就在这里
else if (2 == nKey) //双倍长Key(16字节)
{
j -= 2;
for (i = 0; i < j;++i)
{
Xor(input + 8 * (i + 1), output, 8, output);
RunDes(output, 0, &bySubKey[0],output); //将输出设定为扭转变量
}
Xor(input + 8 * (++i),output, 8, output); //最后一块数据和上面加密结果异或
RunDes(output, 0,&bySubKey[0], output);
RunDes(output, 1,&bySubKey[1], output);
RunDes(output, 0,&bySubKey[0], output);
}</span>
else //三倍长Key(24字节) 尚未验证
{
//j -= 2;
for (i = 0, j =(nInLen >> 3) - 2; i < j; ++i, input += 8)
{
Xor(input + 8 * (i + 1), output, 8, byTemp);
RunDes(byTemp, 0, &bySubKey[0], output); memcpy(byInitVec, output, 8); //将输出设定为扭转变量
}
Xor(input + 8 * i,output, 8, output);
RunDes(output, 2,&bySubKey[0], output);
RunDes(output, 1,&bySubKey[1], output);
RunDes(output, 0,&bySubKey[0], output);
}
}

3. GP MAC

GP中定义的MAC可以和PBOC中的MAC通过简单计算相互转换,如下:

DATA=84820000100102030405060708800000

ICV=0000000000000000

KEY=404142434445464748494A4B4C4D4E4F

安全通道协议标识ALGSCP=02

 

3DES_MAC_1为PBOC中规定的计算MAC方法

3DES_MAC_1(ICV+DATA,KEY,MAC1)//MAC1=106729A5F51BFC24

 

 

GP_MAC为GP中规定的计算MAC方法,相当于CBC_MAC取后8字节。

DATAL=LAST(DATA,16)

DATAB=COPY(DATA,1,16)

KEY1=COPY(KEY,1,16)

CBC_3DES_EN(ICV+DATAB,KEY1,_DATA) 

XDATA=XOR(_DATA,DATAL)

GP_MAC(XDATA,KEY,MAC2)//MAC2=106729A5F51BFC24

 

在你仔细读了PBOC_MAC源码后,相信你就会理解上面GP_MAC和PBOC_MAC的转换关系了。





文/闫鑫原创转载请注明出处http://blog.csdn.net/yxstars/article/details/38456657

算法系列6《MAC》的更多相关文章

  1. JAVA算法系列 冒泡排序

    java算法系列之排序 手写冒泡 冒泡算是最基础的一个排序算法,简单的可以理解为,每一趟都拿i与i+1进行比较,两个for循环,时间复杂度为 O(n^2),同时本例与选择排序进行了比较,选择排序又叫直 ...

  2. JAVA算法系列 快速排序

    java算法系列之排序 手写快排 首先说一下什么是快排,比冒泡效率要高,快排的基本思路是首先找到一个基准元素,比如数组中最左边的那个位置,作为基准元素key,之后在最左边和最右边设立两个哨兵,i 和 ...

  3. javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例

    栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...

  4. 【Xamarin挖墙脚系列:mac 终端 常用命令+Mac OS X的快捷键+beamoff 】

    原文:[Xamarin挖墙脚系列:mac 终端 常用命令+Mac OS X的快捷键+beamoff ] 基本命令 1.列出文件 ls 参数 目录名        例: 看看驱动目录下有什么:ls /S ...

  5. 三白话经典算法系列 Shell排序实现

    山是包插入的精髓排序排序,这种方法,也被称为窄增量排序.因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元 ...

  6. Atitit s2018.6 s6 doc list on com pc.docx Atitit s2018.6 s6 doc list on com pc.docx  Aitit algo fix 算法系列补充.docx Atiitt 兼容性提示的艺术 attilax总结.docx Atitit 应用程序容器化总结 v2 s66.docx Atitit file cms api

    Atitit s2018.6 s6  doc list on com pc.docx Atitit s2018.6 s6  doc list on com pc.docx  Aitit algo fi ...

  7. 【C#实现漫画算法系列】-判断 2 的乘方

    微信上关注了算法爱好者这个公众号,有一个漫画算法系列的文章生动形象,感觉特别好,给大家推荐一下(没收过广告费哦),原文链接:漫画算法系列.也看到了许多同学用不同的语言来实现算法,作为一枚C#资深爱好的 ...

  8. 玩转算法系列--图论精讲 面试升职必备(Java版)

    第1章 和bobo老师一起,玩转图论算法欢迎大家来到我的新课程:<玩转图论算法>.在这个课程中,我们将一起完整学习图论领域的经典算法,培养大家的图论建模能力.通过这个课程的学习,你将能够真 ...

  9. 数据结构与算法系列——排序(4)_Shell希尔排序

    1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...

  10. 编程作业1.1——sklearn机器学习算法系列之LinearRegression线性回归

    知识点 scikit-learn 对于线性回归提供了比较多的类库,这些类库都可以用来做线性回归分析. 我们也可以使用scikit-learn的线性回归函数,而不是从头开始实现这些算法. 我们将scik ...

随机推荐

  1. im4java开发向导

    0.搜索ImageMagick下载安装 1.Setting up the Environment    引入im4java到classpath    设置图片处理引擎的command searchpa ...

  2. Python批量插入SQL Server数据库

    因为要做性能测试,需要大量造数据到数据库中,于是用python写了点代码去实现,批量插入,一共四张表 简单粗暴地插入10万条数据 import pymssql import random __auth ...

  3. hibernate进阶--一对多映射配置

    hibernate作为一款优秀的ORM框架,广受大家喜爱,也被Java社区公认为持久层的首选.虽然jdbc为Java数据库操 作带来了诸多便利,但是并没有统一SQL语句的写法,而且具体操作数据库的代码 ...

  4. 浅谈 cookie 和 session

    1.关闭浏览器后,session是否还存在? session在服务器和客户端各保留一个副本,关闭浏览器与否和session是否存在没有任何关系. session采取的是服务器端保持状态的方案,它存储在 ...

  5. MVC ueditor的使用(实现上传图片功能)

    之前使用ckeditor不能实现上传图片功能,只要是我不知道怎么使用啦o( ̄ε ̄*),然后就换了ueditor~~,可以实现上传图片功能啦~\(≧▽≦)/~~ 下面是我的步骤:去官网下载最新版uedi ...

  6. Puppet安装与配置简介(附视频教程)

    Puppet是一种Linux平台的集中配置管理系统,他可管理配置文件.用户.cron任务.软件包.系统服务等.puppet把这些系统实体称之为资源,puppet采用C/S星状的结构,所有的客户端和一个 ...

  7. ionic cordova file download and load

    1.先添加插件 cordova plugin add org.apache.cordova.file cordova plugin add org.apache.cordova.file-transf ...

  8. STL源码分析-AVL树-RB树

    AVL树 不平衡情况 插入节点位于左子节点的左子树(左左) 插入节点位于左子节点的右子树(左右) 插入节点位于右子节点的左子树(右左) 插入节点位于右子节点的右子树(右右) 左左.右右为外侧插入,左右 ...

  9. hadoop 根据SecondaryNameNode恢复Namenode

    1.修改conf/core-site.xml 增加 <property> <name>fs.checkpoint.period</name> <value&g ...

  10. ChainOfResponsibility

    #include <iostream> using namespace std; class Chain { public: bool Handle() { return false; } ...