Example #1
0
def process_rule_eps(rule_file_name, cps):
    key = '0123456789ABCDEF1111111111111111'  #默认解密key
    rule_handle = RuleXml(rule_file_name)
    handle8020_node = rule_handle.get_first_node(rule_handle.root_element,
                                                 'Handle8020')
    if not handle8020_node:
        return cps
    key = rule_handle.get_attribute(handle8020_node, 'key')
    for dgi_item in cps.dgi_list:
        if dgi_item.name == '8020':
            tag8020 = ''
            tagA001 = ''
            value = dgi_item.get_value('8020')
            dgi_len = len(value)
            for i in range(0, dgi_len, 34):
                tagA001 += value[i:i + 2] + '010000FF0000'
                data = algorithm.des3_ecb_decrypt(key, value[i + 2:i + 34])
                tag8020 += data
            dgi_item.modify_value('8020', tag8020)
            dgiA001 = Dgi()
            dgiA001.name = 'A001'
            dgiA001.add_tag_value('A001', tagA001)
            cps.add_dgi(dgiA001)
        if dgi_item.name == '9020':
            tag9020 = ''
            value = dgi_item.get_value('9020')
            for i in range(0, len(value), 8):
                tag9020 += value[i + 2:i + 8]
            dgi_item.modify_value('9020', tag9020)
    return cps
Example #2
0
def process_tag_decrypt(rule_file_name, tag, data):
    rule_file = RuleXml(rule_file_name)
    tag_decrypt_nodes = rule_file.get_nodes(rule_file.root_element,
                                            'TagDecrypt')
    for node in tag_decrypt_nodes:
        attrs = rule_file.get_attributes(node)
        if attrs['tag'] == tag:
            start_pos = 0
            data_len = 0
            delete80 = False
            is_bcd = False
            data = algorithm.des3_ecb_decrypt(attrs['key'], data)
            start_pos = int(attrs['startPos']) if 'startPos' in attrs else 0
            data_len = int(attrs['len']) if 'len' in attrs else len(data)
            delete80 = True if 'delete80' in attrs else False
            is_bcd = True if 'bcd' in attrs else False
            if delete80:
                index = data.rfind('80')
                if index != -1:
                    data = data[:42]
            if is_bcd:
                data = utils.bcd_to_str(data)
            data = data[start_pos:start_pos + data_len]
            return data
    return data
Example #3
0
def parse_A006(xml, goldpac_dgi_list):
    sddf_A006 = get_sddf_tag(xml, 'EMVDataName', 'Kidn')
    dgi = Dgi()
    dgi.name = 'A006'
    data = get_goldpac_data(goldpac_dgi_list, sddf_A006, False)
    rule_file_handle = RuleXml(xml.file_name)
    _, key = rule_file_handle.get_decrypted_attribute('A006')  #顺带解密
    data = algorithm.des3_ecb_decrypt(key, data)
    dgi.add_tag_value(dgi.name, data)
    return dgi
Example #4
0
 def _process_decrypt(self, key, key_type, data, is_delete80):
     if key_type == 'DES':
         data = algorithm.des3_ecb_decrypt(key, data)
     elif key_type == 'SM':
         data = algorithm.sm4_ecb_decrypt(key, data)
     elif key_type == 'BASE64':
         data = utils.base64_to_bcd(data)
     elif key_type == 'BCD':
         data = utils.str_to_bcd(data)
     if is_delete80:
         index = data.rfind('80')
         data = data[0:index]
     return data
Example #5
0
    def parse_store_data(self,
                         app_type,
                         dgi_name,
                         data,
                         session_key=None,
                         is_encrypted=False,
                         delete80_list=[]):
        int_dgi_name = int(dgi_name, 16)
        if is_encrypted and session_key:
            data = des3_ecb_decrypt(session_key, data)
            if dgi_name in delete80_list:
                index = data.rfind('80')
                if index != -1:
                    data = data[0:index]

        #对于PSE和PPSE,不解析TLV格式
        if app_type in ('PSE', 'PPSE'):
            dgi = Dgi()
            dgi.name = app_type
            if data.startswith('70'):
                data = data[4:]  #去掉70模板
            dgi.add_tag_value(dgi_name, data)
            return dgi
        else:
            #规则如下:
            #1. 小于0x0B00的记录数据需要解析TLV结构
            #2. 如果DGI大于0B00,并且该数据可以解析成TLV,则分如下情况
            #   a. 如果是8000,9000,9102,9103等不需要分析TLV结构的,则不分析
            #   b. 如果DGI以A,B字母开头(万事达应用),不用做TLV分析
            if int_dgi_name <= 0x0B00 \
                or (dgi_name not in self.do_not_parse_tlv_list \
                    and utils.is_tlv(data)\
                    and not (dgi_name.startswith('A') or dgi_name.startswith('B')) ):
                if utils.is_tlv(data):
                    tlvs = utils.parse_tlv(data)
                    return self._assemble_dgi(dgi_name, tlvs)
                else:
                    dgi = Dgi()
                    dgi.name = dgi_name
                    dgi.add_tag_value(dgi_name, data)
                    return dgi
            else:
                dgi = Dgi()
                dgi.name = dgi_name
                if dgi_name.endswith('_2'):
                    dgi_name = dgi_name[:-2]
                dgi.add_tag_value(dgi_name, data)
                return dgi
Example #6
0
def parse_8000(xml, goldpac_dgi_list, is_second_app):
    sddf_8000_ac = get_sddf_tag(xml, 'EMVDataName', 'Kac')
    sddf_8000_mac = get_sddf_tag(xml, 'EMVDataName', 'Ksmi')
    sddf_8000_enc = get_sddf_tag(xml, 'EMVDataName', 'Ksmc')
    dgi = Dgi()
    if is_second_app:
        dgi.name = '8000_2'
    else:
        dgi.name = '8000'
    data = get_goldpac_data(goldpac_dgi_list, sddf_8000_ac, is_second_app)
    data += get_goldpac_data(goldpac_dgi_list, sddf_8000_mac, is_second_app)
    data += get_goldpac_data(goldpac_dgi_list, sddf_8000_enc, is_second_app)
    rule_file_handle = RuleXml(xml.file_name)
    _, key = rule_file_handle.get_decrypted_attribute('8000')  #顺带解密
    data = algorithm.des3_ecb_decrypt(key, data)
    dgi.add_tag_value(dgi.name, data)
    return dgi
Example #7
0
def split_rsa(xml, goldpac_dgi_list, is_second_app):
    rule_file_handle = RuleXml(xml.file_name)
    _, key = rule_file_handle.get_decrypted_attribute('RSA')
    sddf_tag = ''
    _, sddf_tag, _ = rule_file_handle.get_tag_link_attribute(
        'EMVDataName', 'Icc_KeyPair')
    if is_second_app:
        sddf_tag = sddf_tag[0:4] + get_second_app_index() + sddf_tag[5:8]
    else:
        sddf_tag = sddf_tag[0:4] + get_first_app_index() + sddf_tag[5:8]
    encrypted_data = get_goldpac_data(goldpac_dgi_list, sddf_tag,
                                      is_second_app)
    if encrypted_data is None:
        Log.error('无法获取RSA数据[tag' + sddf_tag + ']缺少数据')
    decrypted_data = algorithm.des3_ecb_decrypt(key, encrypted_data)
    if len(decrypted_data) <= 2 or decrypted_data[0:2] != '30':
        Log.error('RSA解密失败')
        return None
    decrypted_data = decrypted_data[2:]
    _, decrypted_data = get_rsa_dgi_len(decrypted_data)
    dgi_list = []
    for i in range(9):
        decrypted_data = decrypted_data[2:]  #remove flag '02'
        dgi_len, decrypted_data = get_rsa_dgi_len(decrypted_data)
        dgi_data = get_rsa_dgi_value(decrypted_data, dgi_len)
        decrypted_data = decrypted_data[dgi_len:]
        dgi = Dgi()
        if is_second_app:
            dgi.name = '_2'
        if i == 4:
            dgi.name = '8205' + dgi.name
        elif i == 5:
            dgi.name = '8204' + dgi.name
        elif i == 6:
            dgi.name = '8203' + dgi.name
        elif i == 7:
            dgi.name = '8202' + dgi.name
        elif i == 8:
            dgi.name = '8201' + dgi.name
        else:
            continue
        dgi.add_tag_value(dgi.name[0:4], dgi_data)
        dgi_list.append(dgi)
        Log.info(dgi.name[0:4] + '=' + dgi_data)
    return dgi_list
Example #8
0
def process_tag_decrypt(rule_file_name,tag,data):
    rule_file = RuleXml(rule_file_name)
    tag_decrypt_nodes = rule_file.get_nodes(rule_file.root_element,'TagDecrypt')
    for node in tag_decrypt_nodes:
        attrs = rule_file.get_attributes(node)
        if attrs['tag'] == tag:
            data = algorithm.des3_ecb_decrypt(attrs['key'],data)
            if 'startPos' in attrs:
                start_pos = int(attrs['startPos'])
            else:
                start_pos = 0
            if 'len' in attrs:
                data_len = int(attrs['len'])
            else:
                data_len = len(data)
            data = data[start_pos : start_pos + data_len]
            return data
    return data
Example #9
0
def process_mag_data(fh,rule_file_name):
    rule_file = RuleXml(rule_file_name)
    mag_node = rule_file.get_first_node(rule_file.root_element,'Magstrip')
    
    mag_flag = fh.read_str(fh.current_offset,6)
    if mag_flag != '000MAG':
        return False
    mag_data_len = fh.read_int64(fh.current_offset)
    track_flag_list = []
    track_flag_list.append(fh.read(fh.current_offset,1))
    track_flag_list.append(fh.read(fh.current_offset + 1,1))
    track_flag_list.append(fh.read(fh.current_offset + 1,1))
    mag_data = fh.read_binary(fh.current_offset,mag_data_len - 5)
    mag_data_list = [x for x in mag_data.split('7C') if len(x) > 0]
    Log.info('decrypt mag data: ',end='')
    Log.info(mag_data_list)
    dgi = Dgi()
    dgi.name = 'Magstrip'
    if mag_node is not None:
        mag_key = rule_file.get_attribute(mag_node,'key')
        decrypt_mag_list = []
        for data in mag_data_list:
            data = utils.bcd_to_str(data)
            data = algorithm.des3_ecb_decrypt(mag_key,data)
            data = utils.bcd_to_str(data)
            data_len = int(data[0:4])
            data = data[4:data_len + 4].rstrip()
            decrypt_mag_list.append(data)
        pos = 1
        for mag in decrypt_mag_list:
            for index in range(pos,4):
                pos += 1
                option = 'mag' + str(pos)
                if track_flag_list[index - 1] == '0':
                    dgi.add_tag_value(option,'')
                    continue
                dgi.add_tag_value(option,mag)
                break
        Log.info('decrypt mag data: ',end='')
        Log.info(decrypt_mag_list)
    return dgi