例如我有像这样的R-APDU
uchar rApdu[] = {0x6F, 0x35 ,0x84 ,0x08 ,0x45 ,0x4F ,0x50 ,
0x43 ,0x43 ,0x41 ,0x52 ,0x44 ,0xA5 ,0x29 ,0x50 ,0x06 ,0x55 ,0x5A ,0x4B ,0x41 ,0x52 ,0x54 ,0x5F,
0x2D, 0x06 ,0x75 ,0x7A ,0x72 ,0x75 ,0x65 ,0x6E ,0x87 ,0x01 ,0x01 ,0x9F ,0x11 ,0x01 ,0x01 ,0x9F,
0x12 ,0x06 ,0x55 ,0x5A ,0x4B ,0x41 ,0x52 ,0x54 ,0xBF ,0x0C ,0x05 ,0x9F ,0x4D ,0x02 ,0x0B ,0x0A};
我想在C中解析这个TLV,就像在这个页面上一样:parsed TLV
它应该解析所有标签及其值并接受结构。 我试图解析这就是我得到的东西:
#include <stdio.h>
#include <stdlib.h>
#define uchar unsigned char
#define uint unsigned int
#define ushort unsigned short
#define k6f 0x6F
typedef enum{
false,
true
}bool;
struct TAG{
uchar *data;
uint len;
};
struct TLVdata{
struct TAG s6F;
struct TAG s84;
struct TAG sA5;
struct TAG s50;
struct TAG s5F2D;
struct TAG s87;
struct TAG s9F11;
struct TAG s9F12;
struct TAG sBF0C;
struct TAG s9F4D;
};
static int readTLV(uchar rApdu[]);
int main(void){
uchar rApdu[] = {0x6F, 0x35 ,0x84 ,0x08 ,0x45 ,0x4F ,0x50 ,
0x43 ,0x43 ,0x41 ,0x52 ,0x44 ,0xA5 ,0x29 ,0x50 ,0x06 ,0x55 ,0x5A ,0x4B ,0x41 ,0x52 ,0x54 ,0x5F,
0x2D, 0x06 ,0x75 ,0x7A ,0x72 ,0x75 ,0x65 ,0x6E ,0x87 ,0x01 ,0x01 ,0x9F ,0x11 ,0x01 ,0x01 ,0x9F,
0x12 ,0x06 ,0x55 ,0x5A ,0x4B ,0x41 ,0x52 ,0x54 ,0xBF ,0x0C ,0x05 ,0x9F ,0x4D ,0x02 ,0x0B ,0x0A};
if (readTLV(rApdu) == 0)
printf("ok!\n");
system("PAUSE");
return false;
}
static int readTLV(uchar rApdu[]){
uint i, j, aLen, tLen, tlvIndex;
struct TLVdata newtlv;
aLen = sizeof(rApdu);
tlvIndex = 0;
switch(rApdu[tlvIndex]){
case k6f:
tLen = (int)rApdu[++tlvIndex];
for(i=0; i <= tLen; i++, ++tlvIndex){
if(rApdu[tlvIndex] == 0x84){
newtlv.s84.len = (int)rApdu[++tlvIndex];
++tlvIndex;
newtlv.s84.data = (char*)malloc(10*sizeof(char));
for(j=0; j < newtlv.s84.len; j++, ++tlvIndex){
newtlv.s84.data[j] = rApdu[tlvIndex];
}
newtlv.s84.data[j] = '\0';
printf("%s\n", newtlv.s84.data);
}
}
break;
}
return 0;
}
我找到了一个解析器。只有它是用Java编写的,或者不知道用什么语言编写。有人可以帮忙吗? apduparser
答案 0 :(得分:2)
要实施EMV TLV数据解析,您需要遵循 ISO 8825-1 BER-TLV 编码规则,也称为 ASN.1基本编码规则(BER)。
简而言之,要提取正确的BER-TLV 值,您需要分析标记和长度位以获得正确的大小。
然后你的样本缓冲区将是这样的:
tag: "6F"
len: "35" # // 53
val:#"8408454F504343415244A5295006555A4B4152545F2D06757A7275656E87..0B0A"
- x84:#"8408454F504343415244"
- tag: "84"
- len: "08" # // 8
- val: "454F504343415244"
- xA5:#"A5295006555A4B4152545F2D06757A7275656E8701019F1101019F120655..0B0A"
- tag: "A5"
- len: "29" # // 41
- val:#"5006555A4B4152545F2D06757A7275656E8701019F1101019F1206555A4B..0B0A"
- x50:#"5006555A4B415254"
- tag: "50"
- len: "06" # // 6
- val: "555A4B415254"
- x5F2D:#"5F2D06757A7275656E"
- tag: "5F2D"
- len: "06" # // 6
- val: "757A7275656E"
- x87:#"870101"
- tag: "87"
- len: "01" # // 1
- val: "01"
- x9F11:#"9F110101"
- tag: "9F11"
- len: "01" # // 1
- val: "01"
- x9F12:#"9F1206555A4B415254"
- tag: "9F12"
- len: "06" # // 6
- val: "555A4B415254"
- xBF0C:#"BF0C059F4D020B0A"
- tag: "BF0C"
- len: "05" # // 5
- val:#"9F4D020B0A"
- x9F4D:#"9F4D020B0A"
- tag: "9F4D"
- len: "02" # // 2
- val: "0B0A"
或者,如果您希望应用EMV分析:
# Cheef's parser.
# lib : "/lib/EMV/" - EMV - Integrated Circuit Card Specifications for Payment Systems
# node : "TLVs"
TLVs:#"6F358408454F504343415244A5295006555A4B4152545F2D06757A727565..0B0A" # EMV, Tag + Length + Value (TLV) series
- x6F:#"6F358408454F504343415244A5295006555A4B4152545F2D06757A727565..0B0A" # ISO 7816, Template, File Control Parameters and File Management Data (FCI)
- tag: "6F"
- len: "35" # // 53
- val:#"8408454F504343415244A5295006555A4B4152545F2D06757A7275656E87..0B0A"
- x84:#"8408454F504343415244" # EMV, Dedicated File (DF) Name
- tag: "84"
- len: "08" # // 8
- val:#"454F504343415244" # Dedicated File (DF) Name.
- RID: "454F504343" # Registered Application Provider Identifier (RID)
- PIX: "415244" # Proprietary Application Identifier Extension (PIX)
- xA5:#"A5295006555A4B4152545F2D06757A7275656E8701019F1101019F120655..0B0A" # EMV, Template, FCI A5
- tag: "A5"
- len: "29" # // 41
- val:#"5006555A4B4152545F2D06757A7275656E8701019F1101019F1206555A4B..0B0A"
- x50:#"5006555A4B415254" # ISO 7816, Application Label
- tag: "50"
- len: "06" # // 6
- val: "555A4B415254" # Application Label. // UZKART
- x5F2D:#"5F2D06757A7275656E" # ISO 7816, Language Preference
- tag: "5F2D"
- len: "06" # // 6
- val:#"757A7275656E" # Language Preference. // uzruen
- A21: "uz" # ISO 639, Language Code (a2) // Uzbek
- A22: "ru" # ISO 639, Language Code (a2) // Russian
- A23: "en" # ISO 639, Language Code (a2) // English
- x87:#"870101" # EMV, Application Priority Indicator
- tag: "87"
- len: "01" # // 1
- val:#"01" # Application Priority Indicator.
- S01: "0" # // Application may be selected without confirmation of cardholder
- S02: "1" # // No priority assigned
- x9F11:#"9F110101" # EMV, Issuer Code Table Index
- tag: "9F11"
- len: "01" # // 1
- val: "01" # Issuer Code Table Index. // ISO 8859, Part 1
- x9F12:#"9F1206555A4B415254" # EMV, Application Preferred Name
- tag: "9F12"
- len: "06" # // 6
- val: "555A4B415254" # Name, Application Preferred. // UZKART
- xBF0C:#"BF0C059F4D020B0A" # EMV, FCI Issuer Discretionary Data
- tag: "BF0C"
- len: "05" # // 5
- val:#"9F4D020B0A" # FCI Issuer Discretionary Data.
- x9F4D:#"9F4D020B0A" # EMV, Log Entry
- tag: "9F4D"
- len: "02" # // 2
- val:#"0B0A" # Log Entry.
- B01: "0B" # SFI containing the cyclic transaction log file (binary) // 11
- B02: "0A" # Maximum number of records in the transaction log file (binary) // 10
答案 1 :(得分:0)
我可以提供以下代码来解析BER-TLV:
int parseTlv(const unsigned char *buffer, int length, void* ctx, int (*tagCallback)(void* ctx, int tag, int length, const unsigned char* value)) {
while(length>0) {
// Get tag
int tag=*(buffer++);
int tagLength,tmp;
length--;
if((tag&0x1F)==0x1F) {
if((length--)==0) return -1;
tag=(tag<<8)|*(buffer++);
if((tag&0x80)==0x80) {
if((length--)==0) return -1;
tag=(tag<<8)|*(buffer++);
if((tag&0x80)==0x80) {
if((length--)==0) return -1;
tag=(tag<<8)|*(buffer++);
if((tag&0x80)==0x80) {
// Longer tags are NOT supported
return -1;
}
}
}
} else {
if(tag==0) {
continue;
}
}
// Get length
if((length--)==0) return -1;
tmp=*(buffer++);
tagLength=0;
switch(tmp) {
case 0x84:
if((length--)==0) return -1;
tagLength=*(buffer++);
/* no break */
case 0x83:
if((length--)==0) return -1;
tagLength=(tagLength<<8)|*(buffer++);
/* no break */
case 0x82:
if((length--)==0) return -1;
tagLength=(tagLength<<8)|*(buffer++);
/* no break */
case 0x81:
if((length--)==0) return -1;
tagLength=(tagLength<<8)|*(buffer++);
break;
default:
if(tmp>=0x80) {
// Other 8x variants are NOT supported
return -1;
}
tagLength=tmp;
break;
}
// Check value
if(tagLength>length) return -1;
// Process tag
if(tagCallback(ctx, tag, tagLength, buffer)<0) {
return -1;
}
buffer+=tagLength;
length-=tagLength;
}
return 0;
}