При анализе EMV TLV иногда не отображаются построенные значения (дочерние элементы) - PullRequest
1 голос
/ 06 марта 2019

Мой метод parseTLV() иногда не корректно опускается в построенные значения (дочерние значения TLV).Я использую фильтр ((tag & 0x20)! = 0) для обнаружения построенных значений, но иногда он не работает должным образом.

Например,

70178C159F02069F03069F1A0295055F2A029A039C019F3704

приводит к следующему результату для parseTLV:

  • Метка: 70 - Значение: 8C159F02069F03069F1A0295055F2A029A039C019F3704
  • Метка: 8C - Значение: 9F02069F03069F1A0295055F2A029A039C019F3704

Однако я бы ожидалполучить

  • Метка: 70 - Значение: 8C159F02069F03069F1A0295055F2A029A039C019F3704
  • Метка: 8C - Значение: 9F02069F03069F1A0295055F2A029A039C019F3704
    • Метка: 9F02- Значение: 06
    • Метка: 9F03 - Значение: 06
    • Метка: 9F1A - Значение: 02
    • Метка: 95 - значение: 05
    • тег: 5F2A - значение: 02
    • тег: 9A - значение: 03
    • тег: 9C - значение: 01
    • тег: 9F37 - значение: 04
private ITlv.ITlvDataObjList parseTLV(byte[] src) {
    try {
        if (isBytesEmpty(src)) {
            return null;
        }
        _tlvList = _tlv.createTlvDataObjectList();
        int start = 0;
        int end = start + src.length;
        while (start < end) {
            // tag has 1 byte (0xFF)
            int tag = src[start++] & 0xFF;
            //
            if (tag == 0x00 || tag == 0xFF) {
                continue;
            }
            // tag has more bytes?
            if ((tag & 0x1F) == 0x1F) {
                if (start >= src.length) {
                    break;
                }
                // tag has 2 bytes (0xFFFF)
                tag = (tag << 8) | src[start++] & 0xFF;
                // tag has 3 bytes (0xFFFFFF)
                if ((tag & 0x80) != 0) {
                    if (start >= src.length) {
                        break;
                    }
                    tag = (tag << 8) | src[start++] & 0xFF;
                }
                // break when tag > 3 bytes
                if ((tag & 0x80) != 0) {
                    continue;
                }
            }
            // length 1 byte (0x7F)
            int length = src[start++] & 0xFF;
            // length has more bytes?
            if (length >= 0x80) {
                // break when length > 2 bytes 
                int count = length & 0x7F;
                if (count > 3) {
                    continue;
                }
                // length 1 bytes (0x80-0xFF) or 2 bytes (0x100-0xFFFF)
                length = 0;
                for (int k = 0; k < count; k++) {
                    if (start >= src.length) {
                        break;
                    }
                    length = (length << 8) | src[start++] & 0xFF;
                }
            }
            // values
            byte[] value = new byte[length];
            System.arraycopy(src, start, value, 0, length);
            //
            // create tlv object
            ITlv.ITlvDataObj tlvObj = _tlv.createTlvDataObject();
            tlvObj.setTag(tag);
            tlvObj.setValue(value);
            // save tlv object to list
            _tlvList.addDataObj(tlvObj);
            //
            // next tag
            while (tag > 0xFF) {
                tag = tag >> 8;
            }
            // is constructed (has child)?
            if ((tag & 0x20) != 0) {
                continue;
            }
            start = start + value.length;
        }
        return _tlvList;
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

Ответы [ 2 ]

1 голос
/ 06 марта 2019

Тег 8C не содержит созданного значения. Следовательно, ваш тест на ((tag & 0x20) != 0) не прошел правильно. Вместо этого этот TLV содержит список объектов данных в качестве значения. Если вы посмотрите на значение 9F02069F03069F1A0295055F2A029A039C019F3704, то обнаружите, что это не полные объекты TLV, а только теги + длины.

Следовательно, по тегу вам нужно будет выяснить, содержит ли этот объект TLV список объектов данных. Затем вы можете проанализировать этот список аналогично анализу полных объектов TLV, за исключением того, что пропустите пустое поле значения.

0 голосов
/ 06 марта 2019

Если стандарты EMV не соблюдаются полностью, ваш код может дать сбой по нижеуказанным причинам

  • Теги могут быть длиннее двух байтов (из кода вы не обрабатываете теги более двух байтов. Однако вероятность их появления невелика)
  • Длина может быть больше байта (хотя обычно длина составляет один байт).
  • Любой новый тег, введенный EMV, потерпит неудачу, если вы попытаетесь сравнить теги со списком (игнорируйте это, если вы этого не сделаете).

EMV 4.3. Книга 3, Приложение B Правила для объектов данных BER-TLV, разделы B1, B2, B3 - это правильное место для поиска. Если вы будете точно следовать этому, всего вышеперечисленного можно избежать.

...