EMV TLV Java Function
Asked Answered
B

4

6

I'm looking for a way to translate an EMV response with Java like with this online option:

http://www.emvlab.org/tlvutils/

where you put something like this EMV response:

6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

and it will show you everything perfectly, I started doing something by myself but then I realize that maybe we could have two 9F38(PDOL) Strings not neccesary two same tags cuz I know it's impossible but maybe the value of a tag end in 9F and the start of the next tag would be 38 and that would give me an error... Now that I mention it, is that possible? cuz that was one of the main reasons why I stopped doing my own function..

Does any of you have written a function to do this already?

Thanks!

Broads answered 4/5, 2013 at 0:40 Comment(0)
S
9

https://github.com/binaryfoo/emv-bertlv should do the trick.

Using your example, the following code:

List<DecodedData> decoded = new RootDecoder().decode("6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02", "EMV", "constructed");
new DecodedWriter(System.out).write(decoded, "");

Will output:

[6F (FCI template)] 8407A0000000031010A52F500B56495341204352454449548701015F...1A02
[84 (dedicated file name)] A0000000031010
[A5 (FCI proprietary template)] 500B56495341204352454449548701015F2D086573656E707466729F...1A02
  [50 (application label)] VISA CREDIT
  [87 (application priority indicator)] 01
  [5F2D (language preference)] esenptfr
  [9F12 (application preferred name)] CREDITO
  [9F11 (issuer code table index)] 01
  [9F38 (PDOL - Processing data object list)] 9F1A02
    9F1A (terminal country code) 2 bytes
Somber answered 7/11, 2014 at 12:44 Comment(1)
How can i get particular value from this listColombia
G
3

This project has code to deal with EMV data http://code.google.com/p/javaemvreader/

Guzel answered 18/12, 2013 at 11:4 Comment(0)
G
1

You are on the right track. You can easily build your own EMV parser using the technique call TLV (Tag Length Value). Your raw data always comes back with a Tag, then after the tag is the length, using the length can get you the value.

So create three methods

method 1: Contains all the short tags method 2: Contains all the long tags method 3: Contains all the proprietary tags

So when you pass in your raw emv tag:

6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

Loop through all those three methods, it will give you all the nice information that you need.

Galantine answered 1/3, 2017 at 7:8 Comment(0)
I
0

Use below function which will gives you hashmap of TLV value

public LinkedHashMap parseBERTLVTag(String tlv) throws DecoderException
{
    if(tlv==null || "".equalsIgnoreCase(tlv)){
        return null;
    }

    System.out.println("============= START ["+tlv+"]==================");


    boolean inTagRead= true;
    Map<String,String> tags= new HashMap<>();

    StringBuilder _tmp = new StringBuilder();
    String lastTag = "";
    int old_index = 0;
    boolean isFirstTagByte = true;
    int len = 0;
    boolean more=true;
    String data = "";
    while (more)
    {
        len = 0;
        String hByte = tlv.substring(old_index,(old_index = old_index+2));
        if(inTagRead)
        {
            if(isLastTagByte(hByte, isFirstTagByte))
            {
                inTagRead=false;
                _tmp.append(hByte);
                lastTag =  _tmp.toString();
                System.out.println("Tag["+lastTag+"]");
                tags.put(lastTag, null);
                _tmp= new StringBuilder();
            }else
            {
                _tmp.append(hByte);
            }

            isFirstTagByte = false;

        }else//Length
        {

            isFirstTagByte = true;


            if(isLastLengthByte(hByte)) {
                inTagRead=true;
                _tmp.append(hByte);
                len =  Integer.parseInt(_tmp.toString(), 16 );
                //read len*2
                System.out.println(" Length ["+len+"]");
                data =  tlv.substring(old_index, (old_index = old_index+len*2));
                String tmpData= lastTag+":"+_tmp.toString()+":h"+data;
                System.out.println(" Data ["+tmpData+"]");
                _tmp = new StringBuilder();

                tags.put(lastTag, tmpData);

            }else
            {
                _tmp.append(hByte);
            }

        }

        more= tlv.length()<=old_index?false:true;

        System.out.println("tag "+lastTag+" value "+data+"  length "+len);

        if(lastTag.length() > 0 && data.length() > 0 && len > 0){

            if(!map.containsKey(lastTag)){

                map.put(lastTag,new TLVModel().setTag(lastTag).setLength(len).setValue(data));
            }
        }

    }//END OF WHILE


    System.out.println("------------  as MAP  ---------------------");
    System.out.println("size "+map.size());

    for (Map.Entry mp:map.entrySet()){
        System.out.println("key  "+mp.getKey()+"  value "+mp.getValue());
    }

    return map.size() > 0 ? map : null;
}
Indecent answered 25/9, 2019 at 7:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.