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
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
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
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
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
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
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
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
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