Ejemplo n.º 1
0
def get_len(fh):
    data_len = 0
    data_str_len = fh.read_binary(fh.current_offset, 1)
    if data_str_len == '82':
        data_len = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 2))
    elif data_str_len == '81':
        data_len = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 1))
    else:
        data_len = utils.hex_str_to_int(data_str_len)
    return data_len
Ejemplo n.º 2
0
def process_dp(dp_file, rule_file):
    cps_list = []
    fh = FileHandle(dp_file, 'rb+')
    dp_flag = fh.read_binary(fh.current_offset, 7)
    data_len = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 8))
    dgi_count = fh.read_int64(fh.current_offset)
    dgi_list = []
    for i in range(dgi_count):
        dgi_name_len = fh.read_int(fh.current_offset)
        dgi_name = fh.read_str(fh.current_offset, dgi_name_len)
        dgi_list.append(dgi_name)
    card_seq = fh.read_binary(fh.current_offset, 4)
    card_data_len = fh.read_int(fh.current_offset)
    while data_len > fh.current_offset:
        cps = Cps()
        cps.dp_file_path = dp_file
        for item in dgi_list:
            dgi = Dgi()
            start_flag = fh.read_binary(fh.current_offset, 1)
            if start_flag != '86':
                return cps_list
            dgi_len = get_len(fh)
            dgi_name = fh.read_binary(fh.current_offset, 2)
            dgi.name = dgi_name
            dgi_data_len = utils.hex_str_to_int(
                fh.read_binary(fh.current_offset, 1))
            n_dgi_seq = utils.hex_str_to_int(dgi_name)
            if n_dgi_seq <= 0x0B00:  #认为是记录
                template70 = fh.read_binary(fh.current_offset, 1)
                if template70 != '70':
                    return cps_list
                dgi_data_len = get_len(fh)
            dgi_data = fh.read_binary(fh.current_offset, dgi_data_len)
            if item[0:3] == 'PSE':
                dgi = process_pse_and_ppse(dgi_name, dgi_data, 'PSE')
            elif item[0:4] == 'PPSE':
                dgi = process_pse_and_ppse(dgi_name, dgi_data, 'PPSE')
            else:
                if n_dgi_seq <= 0x0B00 or (utils.is_rsa(dgi_name) is False
                                           and utils.is_tlv(dgi_data)):
                    tlvs = utils.parse_tlv(dgi_data)
                    if len(tlvs) > 0 and tlvs[0].is_template is True:
                        value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value)
                        dgi.add_tag_value(dgi_name, value)
                    else:
                        for tlv in tlvs:
                            value = utils.assemble_tlv(tlv.tag, tlv.value)
                            dgi.add_tag_value(tlv.tag, value)
                else:
                    dgi.add_tag_value(dgi_name, dgi_data)
            cps.add_dgi(dgi)
        if rule_file is not None:
            process_rule(rule_file, cps)
        cps_list.append(cps)
    return cps_list
Ejemplo n.º 3
0
def get_rsa_dgi_len(data):
    data_len = 0
    if data[0:2] == '82':
        data_len = 2 * utils.hex_str_to_int(data[2:6])
        data = data[6:]
    elif data[0:2] == '81':
        data_len = 2 * utils.hex_str_to_int(data[2:4])
        data = data[4:]
    else:
        data_len = 2 * utils.hex_str_to_int(data[0:2])
        data = data[2:]
    return data_len, data
Ejemplo n.º 4
0
def process_card_data(fh, rule_file):
    cps = Cps()
    flag = fh.read_str(fh.current_offset, 6)
    if flag != '000EMV':
        return False, cps
    card_data_len = fh.read_int64(fh.current_offset)
    app_count = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 1))
    for app in range(app_count):
        aid_len = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 1))
        aid = fh.read_binary(fh.current_offset, aid_len)
        app_data_len = fh.read_int64(fh.current_offset)
        dgi_list, encrypt_dgi_list = get_dgi_list(fh)
        Log.info('encrypt dgi list :', encrypt_dgi_list)
        for item in dgi_list:
            card_dgi = Dgi()
            dgi = fh.read_binary(fh.current_offset, 2)
            dgi_len = utils.hex_str_to_int(fh.read_binary(
                fh.current_offset, 1))
            dgi_data = fh.read_binary(fh.current_offset, dgi_len)
            n_dgi = utils.hex_str_to_int(dgi)
            card_dgi.dgi = dgi
            if dgi == '0098' or dgi == '0099':
                dgi = process_pse(dgi, dgi_data)
            elif dgi == '0100':
                dgi = process_ppse(dgi, dgi_data)
            else:
                if n_dgi < 0x0B01:
                    if dgi_data[0:2] != '70':
                        return False, cps
                    if dgi_data[2:4] == '81':
                        dgi_data = dgi_data[6:]
                    else:
                        dgi_data = dgi_data[4:]
                if utils.is_rsa(dgi) is False and utils.is_tlv(dgi_data):
                    tlvs = utils.parse_tlv(dgi_data)
                    if len(tlvs) > 0 and tlvs[0].is_template is True:
                        value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value)
                        card_dgi.add_tag_value(dgi, value)
                    else:
                        for tlv in tlvs:
                            value = process_tag_decrypt(
                                rule_file, tlv.tag, tlv.value)
                            value = utils.assemble_tlv(tlv.tag, value)
                            card_dgi.add_tag_value(tlv.tag, value)
                else:
                    card_dgi.add_tag_value(dgi, dgi_data)
            cps.add_dgi(card_dgi)
    return True, cps
Ejemplo n.º 5
0
 def read_int64_reverse(self, offset):
     '''读取4个字节,全部逆序转换为整形'''
     data = self.read_binary(offset, 4)
     hex_str = ''
     for i in range(0, 8, 2):
         hex_str += data[6 - i:6 - i + 2]
     return utils.hex_str_to_int(hex_str)
Ejemplo n.º 6
0
 def read_int_reverse(self, offset):
     '''读取2字节,逆序转换为整形'''
     data = self.read_binary(offset, 2)
     hex_str = ''
     for i in range(0, 4, 2):
         hex_str += data[2 - i:2 - i + 2]
     return utils.hex_str_to_int(hex_str)
Ejemplo n.º 7
0
def get_next_len(fh):
    next_data_len = fh.read_binary(fh.current_offset, 1)
    if next_data_len == '81':
        next_data_len = fh.read_binary(fh.current_offset, 1)
    elif next_data_len == '82':
        next_data_len = fh.read_binary(fh.current_offset, 2)
    return utils.hex_str_to_int(next_data_len)
Ejemplo n.º 8
0
def is_need_delete_template(dgi):
    """
    通过DGI值判断数据中是否包含有模板信息
    """
    need_remove_prefix = False  #检查是否需要删除DGI及模板数据
    if utils.is_hex_str(dgi):
        if utils.hex_str_to_int(dgi) <= 0x0B01:
            need_remove_prefix = True
    return need_remove_prefix
Ejemplo n.º 9
0
def process_dp(dp_file, rule_file):
    fh = FileHandle(dp_file, 'rb+')
    fh.read(fh.current_offset, 8596)  #reserved
    dgi_list = get_dgi_list(fh)
    file_size = fh.file_size
    cps_list = []
    while fh.current_offset < file_size:
        card_seq = fh.read_int64_reverse(fh.current_offset)
        card_data_total_len = fh.read_int_reverse(fh.current_offset)
        cps = Cps()  #存储单个卡片数据
        cps.dp_file_path = dp_file
        pse_and_ppse_dgi = [
            'Store_PSE_1', 'Store_PSE_2', 'Store_PPSE', 'DGIF001'
        ]
        for dgi_name in dgi_list:
            dgi = Dgi()  #存储单个DGI数据
            if dgi_name in pse_and_ppse_dgi:
                if dgi_name == 'Store_PSE_1':
                    dgi = process_pse_and_ppse(fh, dgi_name, True)
                else:
                    dgi = process_pse_and_ppse(fh, dgi_name, False)
                cps.add_dgi(dgi)
                continue
            dgi_mark = fh.read_binary(fh.current_offset, 1)  #DGI标识
            if dgi_mark != '86':
                return
            next_len = get_next_len(fh)
            dgi_seq = fh.read_binary(fh.current_offset, 2)  #读取DGI序号
            dgi.name = dgi_seq
            next_len = get_next_len(fh)
            n_dgi_seq = utils.hex_str_to_int(dgi_seq)
            if n_dgi_seq <= 0x0B00:  #认为是记录
                template70 = fh.read_binary(fh.current_offset, 1)
                if template70 != '70':
                    return
                next_len = get_next_len(fh)
            dgi_data = fh.read_binary(fh.current_offset, next_len)
            if n_dgi_seq <= 0x0B00 or (dgi_seq not in do_not_parse_tlv_list
                                       and utils.is_tlv(dgi_data)):
                tlvs = utils.parse_tlv(dgi_data)
                if len(tlvs) > 0 and tlvs[0].is_template is True:
                    value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value)
                    dgi.add_tag_value(dgi_seq, value)
                else:
                    for tlv in tlvs:
                        value = utils.assemble_tlv(tlv.tag, tlv.value)
                        dgi.add_tag_value(tlv.tag, value)
            else:
                dgi.add_tag_value(dgi_seq, dgi_data)
            cps.add_dgi(dgi)
        if rule_file is not None:
            process_rule(rule_file, cps)
            process_rule_A001(rule_file, cps)
            process_rule_eps(rule_file, cps)
        cps_list.append(cps)
    return cps_list
Ejemplo n.º 10
0
def parse_sddf_element(sddf_tag, value):
    """
    分析SDDFElement节点中Value所组成的金邦达DGI
    并返回金邦达DGI
    """
    sddf_dgis = []
    count = utils.hex_str_to_int(value[0:2])
    temp = value[2:]
    for i in range(count):
        sddf_dgis.append(sddf_tag[0:4] + temp[i * 4:4 + i * 4])
    return sddf_dgis
Ejemplo n.º 11
0
def _custom_sorted(dgi):
    number = 0
    if dgi.name == 'PSE':
        return 0x9FFFFF
    elif dgi.name == 'PPSE':
        return 0xAFFFFF
    elif dgi.name == 'A001':  #扩展应用应放在8020应用秘钥之前
        return 0x8019
    elif dgi.name == '9010':  #9010需放在8010前面个人化 自主产品 同方
        return 0x8009
    elif dgi.name == 'Magstrip':
        return 0x0003
    elif dgi.name == 'Aid':
        return 0x0001
    elif dgi.name == 'Aid_2':
        return 0x0002
    elif '_' in dgi.name:
        value = dgi.name.replace('_', '0')
        number = utils.hex_str_to_int(value)
    else:
        number = utils.hex_str_to_int(dgi.name)
    return number
Ejemplo n.º 12
0
def _process_template_and_dgi(dgi,data):
    int_dgi = utils.hex_str_to_int(dgi)
    data_len = len(data)
    if int_dgi <= 0x0B01 and dgi not in no_need_template_70:
        if data_len >= 0xFF * 2:
            data = '7082' + utils.get_strlen(data) + data
        elif data_len > 0x80 * 2:
            data = '7081' + utils.get_strlen(data) + data
        else:
            data = '70' + utils.get_strlen(data) + data
    if data_len > 0x80 * 2 and is_need_ff00_prefix:
        dgi += 'FF00'
    data = dgi + utils.get_strlen(data) + data
    return data
Ejemplo n.º 13
0
 def read_int64(self, offset):
     '''读取4字节,并将ASCII转化为整形'''
     data = self.read_binary(offset, 4)
     return utils.hex_str_to_int(data)
Ejemplo n.º 14
0
 def read_short(self, offset):
     '''按二进制顺序读取1字节,转换为整形'''
     data = self.read_binary(offset, 1)
     return utils.hex_str_to_int(data)
Ejemplo n.º 15
0
 def _get_install_param(self, data):
     param_len = utils.hex_str_to_int(data[0:2]) * 2
     param = data[2:2 + param_len]
     data = data[2 + param_len:]
     return data, param