8583报文示例

8583报文构成

长度 + 报文头【TPDU + msgHead + msgType(报文/消息类型)】 + 位图 + 各数据域

银联8583签到报文示例

报文为:

0063600049000060320032050108000020000000C0001600007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233

在实际传输报文中,传输的是byte数组,这里用16进制来表示byte数组

其中,各字段的详细数据如下:

长度:0063

报文头:

  • TPDU:6000490000
  • msgHead:603200320501
  • msgType(报文/消息类型):0800
  • 位图:0020000000C00016

数据域: 00007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233

8583手动组包

银联签到报文规范

下图为银联3des签到报文格式说明:

3des签到,即我们将一段报文(byte数组)发送给服务端(这里用的是Poster模拟器),然后服务端进行验证,若验证通过,会下发工作秘钥。而发送的这段报文,需要进行8583组包,组包的数据,通常给到的是String类型(也有可能不是),需要将其转化成byte数组传给服务端,而各个数据域转byte数组会有不同规则。

8583报文数据类型

这里数据类型分为三种:BCD、ASCII、BINARY

数据长度的类型也分为三种:定长、LLVAR不定长、LLLVAR不定长

详细属性的解释见(8583各数据域属性说明https://download.csdn.net/download/weixin_40582843/11169088)

银联3des签到报文组包

数据源

现在开始对银联3des签到报文组包,所用到的字段有(这里只用必须的字段,即上图所示请求格式中标识为M的字段):

长度:未计算
TPDU:6000490000
msgHead:603200320501
msgType(报文/消息类型):0800(银联签到报文格式中,0800代表签到请求)
位图:未计算
各数据域:

  • 11域:“000074”
  • 41域:“12345678”
  • 42域:“123456789123456”
  • 60域:“00000000003”
  • 62域:
    “53657175656E6365204E6F3234393439313030303030313034313831324341383539323931”
  • 63域:“123”

组包

数据域

  • 11域,类型为BCD,属性为n6,压缩时用BCD码表示3个字节的定长域(注:这里的BCD类型,表示出现的‘字符’只会在0-9之间,定长,表示固定长度为6位,即n后的数字6)

    • 即“000074”转为byte数组后,用16进制表示为{0x00,0x00,0x74},为3个字节;
    • 查ascii码表,可以知道“7”用二进制表示为“0011 0111”,“4”用二进制表示为“0011 0100”,这里“74”两个字符便是2个字节了,去掉前4位,用二进制表示为“0111 0100”,用16进制表示为0x74,即为一个字节;
    • “000074”转化后,便是0x00,0x00,0x74,去掉0x前缀后表示为000074
  • 41域,类型为ASCII,属性为ans8,表示8个字节的定长字符域

    • 查ascii码,可知"12345678"转为16进制表示为{0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38},刚好8个字节,去掉0x前缀后为,3132333435363738
  • 42域,类型为ASCII,属性为ans15,为15个字节的定长字符域,表示为313233343536373839313233343536

  • 60域,类型为BCD,属性为n…017,格式为LLLVAR,表示长度最大为17个字节的不定长字符域

    • ​ “00000000003”,长度为11位,用BCD码表示时,长度需为偶数,可以选择左靠右补0或右靠左补0的方式(看业务需求),我使用的poster模拟器中,要求此数据域为左靠右补0,补0后数据为“000000000030“,类比11域的转化,最后的数据用16进制表示为000000000030;
    • ​ 但此数据域为LLLVAR不定长域,需要在数据前用2个字节表示其长度,这里的长度为未补0之前的长度,即11,(长度为BCD的类型,不够3个字节时右靠左补0),最终结果为0011;
    • ​ 即60域最终数据为0011000000000003;
  • 62域,类型为BINARY,属性为b…084,格式为LLLVAR,表示长度最大为84字节的不定长字符域

    • ​ 一般类型为BINARY时,传过来的数据都是byte数组了,这个例子中,用16进制表示byte数组为,“53657175656E6365204E6F3234393439313030303030313034313831324341383539323931”,不需要转换(因为8583报文传输的便是byte数组)
    • ​ 由于是不定长,这里byte数组长度为37,长度压缩时用BCD码表示2个字节,转化后为0037
    • ​ 即62域最终数据为003753657175656E6365204E6F3234393439313030303030313034313831324341383539323931
  • 63域,类型为ASCII,属性为ans…003,格式为LLLVAR,为最多3个字节的不定长字符域

    • ​ 最终数据为0003313233

各数据域连起来的结果为:
00007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233

位图

位图的定义:

在所有的报文中都需要主位元表。它决定消息中包含了哪些数据字段。这些位是从左向右解释的,“1”表示该字段在消息中出现,“0”则表示未出现,第n位指示第n个数据字段。

如果第一位设置为“1”,表示有扩展位元表。

只有当消息中出现第65-128数据字段时,扩展位元表才出现。扩展位元表的描述和主位元表的描述一致。

在此签到报文中,最多只有64域,故无扩展位元表,且主位元表的第一位应设置为0,其他位,若有该字段,则设置为1,否则设置为0,故11,41,42,60,62,63位需设置为1,其它位设置为0

位元表用二进制表示为100000000000000000000000000000110000000000000000010110

转为16进制表示为0020000000C00016

报文头及报文长度

在签到报文的报文头中,数据类型都为定长BCD码,转换后,将 报文头【TPDU + msgHead + msgType(报文/消息类型)】 + 位图 + 各数据域 连接起来,得到的数据用16进制表示为:

600049000060320032050108000020000000C0001600007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233

可以计算出,此数据的长度为99个字节,而字符“99”用2个字节16进制表示为:0x00,0x63

组包

故,报文最终结果为:

0063600049000060320032050108000020000000C0001600007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233

银联签到及消费java代码实例

工具准备

使用poster模拟器进行交易,将模拟器通讯方式设置为tcp

签到结果

https://github.com/suya1994/Demo8583.git

将此报文发送给poster模拟器后,模拟器会返回相应的报文,返回报文62域中含有工作秘钥,表示签到成功;模拟器交易截图为下图:

签到报文工作秘钥解析

/*** 解析签到报文第62域*/
public void unpack62Field(){System.out.println("\n-----start  unpack62Field------");//将62域的数据提出来,分组int contentLength = fields[62].bytesData.length - 2;byte[] content = new byte[contentLength];System.arraycopy(fields[62].bytesData,2,content,0,contentLength);//工作秘钥密文byte[] content1 = Arrays.copyOfRange(content,0,16);byte[] content2 = Arrays.copyOfRange(content,20,36);byte[] content3 = Arrays.copyOfRange(content,40,56);//校验码byte[] check1 = Arrays.copyOfRange(content,16,20);byte[] check2 = Arrays.copyOfRange(content,36,40);byte[] check3 = Arrays.copyOfRange(content,56,60);System.out.println("check1 = " + Utils.bytes2HexStr(check1));System.out.println("check2 = " + Utils.bytes2HexStr(check2));System.out.println("check3 = " + Utils.bytes2HexStr(check3));//用3des解密第62域,主秘钥为16个0x11,解密出三个工作秘钥byte[] key = new byte[]{0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};//解密后的工作秘钥byte[] decrypt1 = EncryptUtil.decryptByDESede(content1,key);byte[] decrypt2 = EncryptUtil.decryptByDESede(content2,key);byte[] decrypt3 = EncryptUtil.decryptByDESede(content3,key);System.out.println("decrypt1 = " + Utils.bytes2HexStr(decrypt1));System.out.println("decrypt2 = " + Utils.bytes2HexStr(decrypt2));System.out.println("decrypt3 = " + Utils.bytes2HexStr(decrypt3));//用工作秘钥给8字节0x00加密,若结果的前4字节和校验码相同,则说明工作秘钥对byte[] encrypt = new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};byte[] decrypt1by3des = EncryptUtil.encryptByDESede(encrypt,decrypt1);byte[] decrypt2by3des = EncryptUtil.encryptByDESede(encrypt,decrypt2);byte[] decrypt3by3des = EncryptUtil.encryptByDESede(encrypt,decrypt3);System.out.println("decrypt1by3des = " + Utils.bytes2HexStr(decrypt1by3des));System.out.println("decrypt2by3des = " + Utils.bytes2HexStr(decrypt2by3des));System.out.println("decrypt3by3des = " + Utils.bytes2HexStr(decrypt3by3des));//前四字节,与校验码对比byte[] _decrypt1by3des = Arrays.copyOf(decrypt1by3des,4);byte[] _decrypt2by3des = Arrays.copyOf(decrypt2by3des,4);byte[] _decrypt3by3des = Arrays.copyOf(decrypt3by3des,4);//若相同,则保存三个工作秘钥if (Arrays.equals(_decrypt1by3des,check1) && Arrays.equals(_decrypt2by3des,check2) && Arrays.equals(_decrypt3by3des,check3)){Pack.key1 = decrypt1;Pack.key2 = decrypt2;Pack.key3 = decrypt3;}System.out.println("-----end  unpack62Field------\n");
}

文中代码:https://github.com/suya1994/Demo8583.git

8583组包解包及银联3des签到消费java示例相关推荐

  1. Java版ISO8583报文组包/解包

    文章目录 一.8583协议简介 二.位图规则 三.8583格式报文参考 四.组包/解包思路 五.相关代码 一.8583协议简介   8583协议是基于ISO8583报文国际标准的包格式的通讯协议,85 ...

  2. C语言字符串的组包解包

    组包解包 sprintf组包 sscanf解包 sscanf的高级用法1:使用%*s %*d 跳过提取的内容(不要提取的内容) sscanf的高级用法2:使用%[n]s %[n]d 提取指定宽度n的字 ...

  3. python3 抓包 解包_Python结构包,解包

    python3 抓包 解包 Python struct module is capable of performing the conversions between the Python value ...

  4. 【各个模块间数据交互通讯及接口定义】串口通讯--压包解包,解析数据帧的方法

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 (1)ROS的分布式通信 (2)串口通讯--压包解包,解析数据帧的方 ...

  5. python unpacking_python packing unpacking 组包解包

    packing 组包,函数使用 [*] (for tuples)[元组], & [**](for dict) [ 字典]来接受可迭代的参数 unpacking 解包 ,函数内部定义多个参数(可 ...

  6. 网络粘包解包问题杂谈

    1.如何解决粘包问题? 在设计网络协议时,可能会存在粘包.丢包或者包乱序问题,但TCP协议时可靠性协议,大多数情况不存在丢包和乱序问题,但UDP协议如果不能接受少量丢包,就必须自己设计有序和可靠性传输 ...

  7. 网络传输粘包解包处理

    有时候发送的数据过长,接收的时候只接收了一部分,会出现错误.这里以客户端接收服务端消息为例,讲解一种解包的方法,作为备忘(总是忘没办法) 1.客户端有一段缓冲区char m_szAnalysisBuf ...

  8. 安卓rom包解包linux,Android rom解包打包工具

    eMMC主要是针对手机和平板电脑等产品的内嵌式存储器,由于其在封装中集成了一个控制器,且提供标准接口并管理闪存等优势,越来越受到Android手机厂商的青睐,以eMMC为存储设备的android手机, ...

  9. 安卓rom包解包linux,[ROM开发]解包打包ROM详细教程 2017.9.8更新安卓7.0

    解包和打包system.img 直接挂载mount system.img /mnt/rom 修改后打包 file_contexts放在当前目录 即打包的img所在目录make_ext4fs -S ./ ...

最新文章

  1. CoordinatorLayout 和 AppBarLayout 实现的局部点击按钮实现折叠和展开
  2. [导入]Eval格式化日期
  3. SpringBoot里slf4j日志功能的默认实现
  4. C++之STL之priority_queue
  5. 票价最低10元 北京大兴国际机场线票价方案正式启用
  6. 微软删除最大的公开人脸识别数据集,只因员工离职?!
  7. Ubuntu 安装 JDK 7 / JDK8 的两种方式
  8. DQL——数据查询语言
  9. iOS中实现plist中读取数据实现Cell的显示(字典转模型,实现按序分组)修改图片的尺寸...
  10. Go黑魔法之导出私有函数与私有变量
  11. 微信内置浏览器缓存清理及关闭微信默认的X5内核
  12. H266 ISP 帧内子划分
  13. windows服务器ie兼容视图信息注册表项
  14. 探究 | Elasticsearch如何物理删除给定期限的历史数据?
  15. WEB前端优化之内容篇
  16. 困惑了很久的函数D3DXCreateTextureFromFileInMemoryEx
  17. 2020年中国第七次人口普查各省总人口数据可视图(1)
  18. 常用Hadoop命令
  19. Panda3D学习 (5):入门教程
  20. 无法识别 移动固态硬盘_M.2接口的固态硬盘无法识别?其实解决方法非常简单!...

热门文章

  1. firefox Chrome浏览器redux devTools调试工具
  2. 程序分析-对程序依赖图(PDG)的理解
  3. 【自然语言处理】【多模态】BLIP:面向统一视觉语言理解和生成的自举语言图像预训练
  4. 学习笔记 之 计算机网络:自顶向下方法(原书第7版)
  5. Java 通过Office365 服务器发送邮件
  6. 二手车 电商+互联网金融的三种新玩法
  7. win10java卸载有残留_win10打开方式仍残留已卸载软件如何解决
  8. 深度学习入门笔记(一):深度学习引言
  9. 四则运算《安卓版》04
  10. simulink中 Bernoulli binary generator(贝努力二进制产生器)各个参数