java mac pos_pos终端mac国密(sm4)算法(java实现)

概念理解

mac算法是(Message Authentication Codes 消息认证码算法),是含有密钥散列函数算法。主要通过异或运算,再配合其他加密算法实现mac值的运算,用于校验。

实现过程

将需要加密计算的字符串转换为16进制字符串

例如:

密钥:"12345678901234567890123456789012"

待加密数据(字符串形式):

6000112018111411003020170930101010120171025000755000000005553

转化为16进制:

36303030 31313230 31383131 31343131 30303330 32303137 30393330 31303130 31303132 30313731 30323530 30303735 35303030 30303030 30353535 33

将转换过的16字符串进行补位分组

部位后的数据(部位规则:字符长度%32!=0补位)

36303030 31313230 31383131 31343131 30303330 32303137 30393330 31303130 31303132 30313731 30323530 30303735 35303030 30303030 30353535 33000000

分组后的数据

第 0组明文:36303030 31313230 31383131 31343131

第 1组明文:30303330 32303137 30393330 31303130

第 2组明文:31303132 30313731 30323530 30303735

第 3组明文:35303030 30303030 30353535 33000000

将分组过的字符串数组逐步进行异或运算

异或流程

第 0组明文: 36303030 31313230 31383131 31343131

第 1组明文: 30303330 32303137 30393330 31303130

第 1组异或结果:06000300 03010307 01010201 00040001

第 2组明文:31303132 30313731 30323530 30303735

第 2组异或结果:37303232 33303436 31333731 30343734

第3组明文:35303030 30303030 30353535 33000000

与第2组密文异或:02000202 03000406 01060204 03343734

将最后异或结果转化为16进制字符串

转换为16进制

30323030 30323032 30333030 30343036 30313036 30323034 30333334 33373334

取前16位和后16位,前16位进行sm4加密,加密结果与后16位异或后再加密

前16位

30323030 30323032 30333030 30343036

后16位

30313036 30323034 30333334 33373334

前16位加密结果

B038A2B2 F3FFE3C8 AC60B377 C70C2DB1

与后16位异或结果

80099284 C3CDD3FC 9C538043 F43B1E85

再加密结果

1E80F373 40B0FEE6 2C81F356 AFB20BF1

取前16个字符作为mac值

mac值:1E80F37340B0FEE6

具体实现过程

准备工作

数据转换工具类 TransferUtils.java

字符串转换为16进制字符串

public static String StringToHexString(String str) {

String data = bytesToHexString(str.getBytes(), 32);

return data;

}

字节数组转换为16进制字符串

/**

* 字节数组转化为十六进制字符串 并按照len的倍数进行补"0"

* @param bytes 字节数据

* @param len 部位原则 不够len倍数补"0"

* @return

*/

public static String bytesToHexString(byte[] bytes, int len) {

StringBuffer hexStr = new StringBuffer();

for (byte b : bytes) {

hexStr.append(String.format("%02x", new Integer(b & 0xff)));

}

//长度不满32的整数倍 在后边添加 "0"

while (hexStr.length() % len != 0) {

hexStr.append("0");

}

return hexStr.toString();

}

将字符串str 按照长度len 进行分组

/**

* 将字符串str 按照长度len 进行分组

* @param str 字符串

* @param len 每组字符长度

* @return

*/

public static String[] dataGrouping(String str, int len) {

int lenth = str.length() % len == 0 ? str.length() / len : str.length() / len + 1;

String[] data = new String[lenth];

for (int i = 0; i < lenth; i++) {

data[i] = str.substring(i * len, i * len + len);

}

return data;

}

将字符串数组进行异或运算

public static String handleXOrStringArr(String[] strs){

String result = "";

for (int i = 1;i < strs.length;i++){

if (i == 1){

result = xOr(strs[0],strs[1]);

}else {

result = xOr(strs[i],result);

}

}

return result;

}

异或运算

/**

* 异或运算

* @param s1

* @param s2

* @return

*/

public static String xOr(String s1, String s2) {

String data = IntArr2String(xOr(String2IntArr(s1),String2IntArr(s2)));

return data;

}

public static int [] xOr(int[] i1,int[] i2){

int[] xor = new int[i1.length];

for (int i = 0;i < i1.length & i < i2.length;i++){

xor[i] = i1[i]^i2[i];

}

return xor;

}

加密工具类

sm4加密

public static byte[] encodeSMS4(byte[] plaintext, byte[] key) {

byte[] ciphertext = new byte[plaintext.length];

int k = 0;

int plainLen = plaintext.length;

while (k + 16 <= plainLen) {

byte[] cellPlain = new byte[16];

for (int i = 0; i < 16; i++) {

cellPlain[i] = plaintext[k + i];

}

byte[] cellCipher = encode16(cellPlain, key);

for (int i = 0; i < cellCipher.length; i++) {

ciphertext[k + i] = cellCipher[i];

}

k += 16;

}

return ciphertext;

}

调用过程

将密钥转换为字节数组,将需要加密计算的字符串转换为16进制字符串并补位

例如:

密钥:"12345678901234567890123456789012"

待加密数据(字符串形式):

6000112018111411003020170930101010120171025000755000000005553

//将key转换为字节数组

byte[] keys = TransformUtils.HexStringToByteArr(key);

//将加密数据转换为16进制字符串

String hexData = TransformUtils.StringToHexString(data);

将转换过的16字符串进行分组

//将数据分组 32位为一组

String[] dataGroup = TransformUtils.dataGrouping(hexData, 32);

将分组过的字符串数组逐步进行异或运算

//进行异或运算

String xorData = TransformUtils.handleXOrStringArr(dataGroup);

将最后异或结果转化为16进制字符串

//将异或结果转化为16进制字符串

String hexOxrData = TransformUtils.StringToHexString(xorData);

取前16字节和后16字节,前16字节进行sm4加密,加密结果与后16字节异或后再加密

//取前16字节和后16字节 两个16进制位表示一个字节

String start32Bit = hexOxrData.substring(0,32);

String end32Bit = hexOxrData.substring(hexOxrData.length() - 32,hexOxrData.length());

//前16位进行首次加密

byte[] encodeSMS4_1 = SMS4.encodeSMS4(TransformUtils.HexStringToByteArr(start32Bit), keys);

//加密结果与后16位进行异或

String xOrEnd = TransformUtils.xOr(TransformUtils.bytesToHexString(encodeSMS4_1, 16), end32Bit);

//异或结果转成字节数组

byte[] bytes = TransformUtils.HexStringToByteArr(xOrEnd);

//进行二次加密

byte[] resultByte = SMS4.encodeSMS4(bytes, keys);

//将加密结果转换成16进制字符串 并取前八个字符作为mac值返回

String result = TransformUtils.bytesToHexString(resultByte, 16);

取前16个字符作为mac值

//取前8字节作为mac值返回

result = result.substring(0,16);

后记

此处是pos终端mac国密(sm4)算法,之前还有一个pos终端mac国际算法(双倍长 3des),两者的区别在于 分组的时候分组长度不太一样,国际是16个16进制字符(8字节)分组,国密是32个16进制字符(16字节)分组,再有不同的地方就是加密算法不同,国密是sm4加密算法,国际是双倍长3des加密算法,其他基本都是一样的,这个加密算法也是根据需求可以进行更改的 ,比如改为RSA 或AES也是可以的,这个就需要双方沟通了 统一加密算法就可以了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php-rpm.conf,在新安装的宝塔面板中php无法启动起来

在新安装的宝塔面板中php无法启动起来去看了网站的报错信息是&#xff1a;[Wed Aug 15 11:00:09.827025 2018] [proxy:error] [pid 4264] (2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /tmp/php-cgi-56.sock (*) failed[Wed Aug 15…

HTML 列表中的dl,dt,dd,ul,li,ol区别及应用

HTML 列表中的dl,dt,dd,ul,li,ol区别及应用 HTML 列表中的dl,dt,dd,ul,li,ol区别及应用 工具/原料 html&#xff0c;dw软件方法/步骤 1无序列表 无序列表是一个项目的列表&#xff0c;此列项目使用粗体圆点&#xff08;典型的小黑圆圈&#xff09;进行标记。 无序列表始于 <…

php pdo mysql 乱码,php pdo连接数据库 解决中文乱码问题(wordpress mysql 问号?? ??)...

摘要&#xff1a;PHP 用pdo连接数据库时出现中文乱码问题解决办法1.array(PDO::MYSQL_ATTR_INIT_COMMAND > "set names utf8"),在与数据库建立连接的时候的第四个参数 example: $dbh new PDO($PHP 用pdo连接数据库时出现中文乱码问题解决办法1.array(PD…

HashMap 与 ConcurrentHashMap

一、概述 二、HashMap 1、数据结构 2、应用 3、不要用 HashMap 做本地缓存 一般我们声明 HashMap 时&#xff0c;使用的都是默认的构造方法&#xff1a;HashMap<K, V>&#xff0c;但是它还有另外一个构造方法&#xff1a;HashMap(int initialCapacity, float loadFactor)…

自然语言10_分类与标注

sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare http://www.tuicool.com/articles/feAfi2 NLTK读书笔记 — …

php会不会被人工智能取代,为什么这9种工作不会被人工智能取代?

人工智能(AI)和机器学习(ML)的能力正在逐渐扩大&#xff0c;尽管如此&#xff0c;总会有一些任务所要求的质量是技术难以复制的&#xff0c;例如创造力、同情心和情感意识。有很多任务非常难以实现自动化&#xff0c;而且有些职业总是需要人的技能。我们从了解技术的各种局限性…

git中Please enter a commit message to explain why this merge is necessary.

Please enter a commit message to explain why this merge is necessary. 请输入提交消息来解释为什么这种合并是必要的 git 在pull或者合并分支的时候有时会遇到这个界面。可以不管(直接下面3,4步)&#xff0c;如果要输入解释的话就需要: 1.按键盘字母 i 进入insert模式 2.修…

php代码显示灰色,哀悼日-实现网页变灰色的方法

哀悼日期间经常需要把网页设置为灰色状态&#xff0c;现总结一下方法以备后用&#xff0c;在网站的CSS文件中的顶部加入如下代码&#xff1a;html{filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale1);-webkit-filter: grayscale(100%);}或者&#xff1a;html *{…

yum阿里云镜像源

阿里云是最近新出的一个镜像源。得益与阿里云的高速发展&#xff0c;这么大的需求&#xff0c;肯定会推出自己的镜像源。阿里云Linux安装镜像源地址&#xff1a;http://mirrors.aliyun.com/ CentOS系统更换软件安装源第一步&#xff1a;备份你的原镜像文件&#xff0c;以免出错…

abp框架mysql连接配置,abp框架连接数据库

ABP框架搭建项目系列教程基础版完结篇经过前面十二篇的基础教程&#xff0c;现在终于该做个总结了。回顾第一篇&#xff0c;我们建议新手朋友们先通过ABP官网的启动模板生成解决方案&#xff0c;因为这样既快速又准确&#xff0c;不会因为项目的搭建&#xff0c;而让新手畏而却…

【分布式】Zookeeper在大型分布式系统中的应用

一、前言 上一篇博文讲解了Zookeeper的典型应用场景&#xff0c;在大数据时代&#xff0c;各种分布式系统层出不穷&#xff0c;其中&#xff0c;有很多系统都直接或间接使用了Zookeeper&#xff0c;用来解决诸如配置管理、分布式通知/协调、集群管理和Master选举等一系列分布式…

php 数组当链表,php数组和链表的区别总结

PHP中数组和链表的区别从逻辑结构来看1.、数组必须事先定义固定的长度(元素个数)&#xff0c;不能适应数据动态地增减的情况。当数据增加时&#xff0c;可能超出原先定义的元素个数&#xff1b;当数据减少时&#xff0c;造成内存浪费&#xff1b;数组可以根据下标直接存取。2、…

Egret资源管理解决方案

关于egret开发H5页游&#xff0c;资源管理和加载的一点看法。 一 多json文件管理 二 资源归类和命名 三 exml文件编写规范 四 资源预加载、分步加载、偷载 五 资源文件group分组 六 ResUtils&#xff0c;多json文件管理类 七 ResUtils&#xff0c;资源组加载管理类 八 开发中遇…

java 等待唤醒机制,Java线程等待唤醒机制

记录面试过程中被问到的几个需要手写代码的小案例1.请手写出线程的等待唤醒机制案例中两个线程&#xff1a;SyncSetThread设置学生信息&#xff0c;SyncGetThread用来获取学生信息&#xff0c;在Student实体中提供一个标记属性flag&#xff0c;记录当前是否有数据。等待唤醒机制…

Xshell实现Windows上传文件到Linux主机

经常有这样的需求&#xff0c;我们在Windows下载的软件包&#xff0c;如何上传到远程Linux主机上&#xff1f;还有如何从Linux主机下载软件包到Windows下&#xff1b;之前我的做法现在看来好笨好繁琐&#xff0c;不过也达到了目的&#xff0c;笨人有本方法嘛&#xff1b; 我是怎…

java实现键盘移动图片,快速移动视图与键盘

我试图在键盘出现时向上移动视图&#xff0c;在键盘隐藏时向下移动 .我遇到的问题是高度似乎不同&#xff1a;KBH1输出216&#xff0c;KBH2输出260 .这导致视图向下移动得比最初移动的距离更远 .我该如何纠正这个&#xff1f;extension UIViewController {func addKeyboardFunc…

python-变量操作-字符串

python对变量&#xff08;不同数据类型&#xff09;的操作 数字操作字符串操作列表操作元组操作集合操作字典操作Python3 中有六个标准的数据类型&#xff1a;Number&#xff08;数字&#xff09;、String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、T…

织梦自适应php源码,DEDE织梦PHP源码响应式建筑设计类网站织梦模板(自适应手机端)...

模板名称&#xff1a;响应式建筑设计类网站织梦模板(自适应移动端) 利于SEO优化模板详情&#xff1a;织梦最新内核开发的模板&#xff0c;该模板属于企业通用、HTML5响应式、建筑设计类企业使用&#xff0c;一款适用性很强的模板&#xff0c;基本可以适合各行业的企业网站&…

nyoj 题目5 Binary String Matching

Binary String Matching 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;3描述Given two strings A and B, whose alphabet consist only ‘0’ and ‘1’. Your task is only to tell how many times does A appear as a substring of B? For…

php array =,PHP Array 函数

PHP Array 函数PHP Array 函数## PHP Array 简介PHP Array 函数允许您访问并操作数组。支持简单的数组和多维数组。## 安装PHP Array 函数是 PHP 核心的组成部分。无需安装即可使用这些函数。## PHP 5 Array 函数| 函数 | 描述 || ------------ | ------------ || array() | 创…