8583组包解包及银联3des签到消费java示例
8583報(bào)文示例
8583報(bào)文構(gòu)成
長(zhǎng)度 + 報(bào)文頭【TPDU + msgHead + msgType(報(bào)文/消息類型)】 + 位圖 + 各數(shù)據(jù)域
銀聯(lián)8583簽到報(bào)文示例
報(bào)文為:
0063600049000060320032050108000020000000C0001600007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233
在實(shí)際傳輸報(bào)文中,傳輸?shù)氖莃yte數(shù)組,這里用16進(jìn)制來表示byte數(shù)組
其中,各字段的詳細(xì)數(shù)據(jù)如下:
長(zhǎng)度:0063
報(bào)文頭:
- TPDU:6000490000
- msgHead:603200320501
- msgType(報(bào)文/消息類型):0800
- 位圖:0020000000C00016
數(shù)據(jù)域: 00007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233
8583手動(dòng)組包
銀聯(lián)簽到報(bào)文規(guī)范
下圖為銀聯(lián)3des簽到報(bào)文格式說明:
3des簽到,即我們將一段報(bào)文(byte數(shù)組)發(fā)送給服務(wù)端(這里用的是Poster模擬器),然后服務(wù)端進(jìn)行驗(yàn)證,若驗(yàn)證通過,會(huì)下發(fā)工作秘鑰。而發(fā)送的這段報(bào)文,需要進(jìn)行8583組包,組包的數(shù)據(jù),通常給到的是String類型(也有可能不是),需要將其轉(zhuǎn)化成byte數(shù)組傳給服務(wù)端,而各個(gè)數(shù)據(jù)域轉(zhuǎn)byte數(shù)組會(huì)有不同規(guī)則。
8583報(bào)文數(shù)據(jù)類型
這里數(shù)據(jù)類型分為三種:BCD、ASCII、BINARY
數(shù)據(jù)長(zhǎng)度的類型也分為三種:定長(zhǎng)、LLVAR不定長(zhǎng)、LLLVAR不定長(zhǎng)
詳細(xì)屬性的解釋見(8583各數(shù)據(jù)域?qū)傩哉f明https://download.csdn.net/download/weixin_40582843/11169088)
銀聯(lián)3des簽到報(bào)文組包
數(shù)據(jù)源
現(xiàn)在開始對(duì)銀聯(lián)3des簽到報(bào)文組包,所用到的字段有(這里只用必須的字段,即上圖所示請(qǐng)求格式中標(biāo)識(shí)為M的字段):
長(zhǎng)度:未計(jì)算
TPDU:6000490000
msgHead:603200320501
msgType(報(bào)文/消息類型):0800(銀聯(lián)簽到報(bào)文格式中,0800代表簽到請(qǐng)求)
位圖:未計(jì)算
各數(shù)據(jù)域:
- 11域:“000074”
- 41域:“12345678”
- 42域:“123456789123456”
- 60域:“00000000003”
- 62域:
“53657175656E6365204E6F3234393439313030303030313034313831324341383539323931” - 63域:“123”
組包
數(shù)據(jù)域
-
11域,類型為BCD,屬性為n6,壓縮時(shí)用BCD碼表示3個(gè)字節(jié)的定長(zhǎng)域(注:這里的BCD類型,表示出現(xiàn)的‘字符’只會(huì)在0-9之間,定長(zhǎng),表示固定長(zhǎng)度為6位,即n后的數(shù)字6)
- 即“000074”轉(zhuǎn)為byte數(shù)組后,用16進(jìn)制表示為{0x00,0x00,0x74},為3個(gè)字節(jié);
- 查ascii碼表,可以知道“7”用二進(jìn)制表示為“0011 0111”,“4”用二進(jìn)制表示為“0011 0100”,這里“74”兩個(gè)字符便是2個(gè)字節(jié)了,去掉前4位,用二進(jìn)制表示為“0111 0100”,用16進(jìn)制表示為0x74,即為一個(gè)字節(jié);
- “000074”轉(zhuǎn)化后,便是0x00,0x00,0x74,去掉0x前綴后表示為000074
-
41域,類型為ASCII,屬性為ans8,表示8個(gè)字節(jié)的定長(zhǎng)字符域
- 查ascii碼,可知"12345678"轉(zhuǎn)為16進(jìn)制表示為{0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38},剛好8個(gè)字節(jié),去掉0x前綴后為,3132333435363738
-
42域,類型為ASCII,屬性為ans15,為15個(gè)字節(jié)的定長(zhǎng)字符域,表示為313233343536373839313233343536
-
60域,類型為BCD,屬性為n…017,格式為L(zhǎng)LLVAR,表示長(zhǎng)度最大為17個(gè)字節(jié)的不定長(zhǎng)字符域
- ? “00000000003”,長(zhǎng)度為11位,用BCD碼表示時(shí),長(zhǎng)度需為偶數(shù),可以選擇左靠右補(bǔ)0或右靠左補(bǔ)0的方式(看業(yè)務(wù)需求),我使用的poster模擬器中,要求此數(shù)據(jù)域?yàn)樽罂坑已a(bǔ)0,補(bǔ)0后數(shù)據(jù)為“000000000030“,類比11域的轉(zhuǎn)化,最后的數(shù)據(jù)用16進(jìn)制表示為000000000030;
- ? 但此數(shù)據(jù)域?yàn)長(zhǎng)LLVAR不定長(zhǎng)域,需要在數(shù)據(jù)前用2個(gè)字節(jié)表示其長(zhǎng)度,這里的長(zhǎng)度為未補(bǔ)0之前的長(zhǎng)度,即11,(長(zhǎng)度為BCD的類型,不夠3個(gè)字節(jié)時(shí)右靠左補(bǔ)0),最終結(jié)果為0011;
- ? 即60域最終數(shù)據(jù)為0011000000000003;
-
62域,類型為BINARY,屬性為b…084,格式為L(zhǎng)LLVAR,表示長(zhǎng)度最大為84字節(jié)的不定長(zhǎng)字符域
- ? 一般類型為BINARY時(shí),傳過來的數(shù)據(jù)都是byte數(shù)組了,這個(gè)例子中,用16進(jìn)制表示byte數(shù)組為,“53657175656E6365204E6F3234393439313030303030313034313831324341383539323931”,不需要轉(zhuǎn)換(因?yàn)?583報(bào)文傳輸?shù)谋闶莃yte數(shù)組)
- ? 由于是不定長(zhǎng),這里byte數(shù)組長(zhǎng)度為37,長(zhǎng)度壓縮時(shí)用BCD碼表示2個(gè)字節(jié),轉(zhuǎn)化后為0037
- ? 即62域最終數(shù)據(jù)為003753657175656E6365204E6F3234393439313030303030313034313831324341383539323931
-
63域,類型為ASCII,屬性為ans…003,格式為L(zhǎng)LLVAR,為最多3個(gè)字節(jié)的不定長(zhǎng)字符域
- ? 最終數(shù)據(jù)為0003313233
各數(shù)據(jù)域連起來的結(jié)果為:
00007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233
位圖
位圖的定義:
在所有的報(bào)文中都需要主位元表。它決定消息中包含了哪些數(shù)據(jù)字段。這些位是從左向右解釋的,“1”表示該字段在消息中出現(xiàn),“0”則表示未出現(xiàn),第n位指示第n個(gè)數(shù)據(jù)字段。
如果第一位設(shè)置為“1”,表示有擴(kuò)展位元表。
只有當(dāng)消息中出現(xiàn)第65-128數(shù)據(jù)字段時(shí),擴(kuò)展位元表才出現(xiàn)。擴(kuò)展位元表的描述和主位元表的描述一致。
在此簽到報(bào)文中,最多只有64域,故無擴(kuò)展位元表,且主位元表的第一位應(yīng)設(shè)置為0,其他位,若有該字段,則設(shè)置為1,否則設(shè)置為0,故11,41,42,60,62,63位需設(shè)置為1,其它位設(shè)置為0
位元表用二進(jìn)制表示為100000000000000000000000000000110000000000000000010110
轉(zhuǎn)為16進(jìn)制表示為0020000000C00016
報(bào)文頭及報(bào)文長(zhǎng)度
在簽到報(bào)文的報(bào)文頭中,數(shù)據(jù)類型都為定長(zhǎng)BCD碼,轉(zhuǎn)換后,將 報(bào)文頭【TPDU + msgHead + msgType(報(bào)文/消息類型)】 + 位圖 + 各數(shù)據(jù)域 連接起來,得到的數(shù)據(jù)用16進(jìn)制表示為:
600049000060320032050108000020000000C0001600007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233
可以計(jì)算出,此數(shù)據(jù)的長(zhǎng)度為99個(gè)字節(jié),而字符“99”用2個(gè)字節(jié)16進(jìn)制表示為:0x00,0x63
組包
故,報(bào)文最終結(jié)果為:
0063600049000060320032050108000020000000C0001600007431323334353637383132333435363738393132333435360011000000000030003753657175656E6365204E6F32343934393130303030303130343138313243413835393239310003313233
銀聯(lián)簽到及消費(fèi)java代碼實(shí)例
工具準(zhǔn)備
使用poster模擬器進(jìn)行交易,將模擬器通訊方式設(shè)置為tcp
簽到結(jié)果
https://github.com/suya1994/Demo8583.git
將此報(bào)文發(fā)送給poster模擬器后,模擬器會(huì)返回相應(yīng)的報(bào)文,返回報(bào)文62域中含有工作秘鑰,表示簽到成功;模擬器交易截圖為下圖:
簽到報(bào)文工作秘鑰解析
/*** 解析簽到報(bào)文第62域*/ public void unpack62Field(){System.out.println("\n-----start unpack62Field------");//將62域的數(shù)據(jù)提出來,分組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);//校驗(yàn)碼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個(gè)0x11,解密出三個(gè)工作秘鑰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字節(jié)0x00加密,若結(jié)果的前4字節(jié)和校驗(yàn)碼相同,則說明工作秘鑰對(duì)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));//前四字節(jié),與校驗(yàn)碼對(duì)比byte[] _decrypt1by3des = Arrays.copyOf(decrypt1by3des,4);byte[] _decrypt2by3des = Arrays.copyOf(decrypt2by3des,4);byte[] _decrypt3by3des = Arrays.copyOf(decrypt3by3des,4);//若相同,則保存三個(gè)工作秘鑰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
總結(jié)
以上是生活随笔為你收集整理的8583组包解包及银联3des签到消费java示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BGP实战拓扑
- 下一篇: 黑客正利用“Black Lives Ma