#! /usr/bin/env python | |
# -*- coding: utf-8 | |
# vim: tabstop=4 | |
import pyDes | |
import codecs | |
def desencrypt(key, data, m=pyDes.ECB): | |
k = pyDes.des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m) | |
return k.encrypt(data) | |
def desdecrypt(key, data, m=pyDes.ECB): | |
k = pyDes.des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m) | |
return k.decrypt(data) | |
def tripledesencrypt(key, data, m=pyDes.ECB): | |
k = pyDes.triple_des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m) | |
return k.encrypt(data) | |
def tripledesdecrypt(key, data, m=pyDes.ECB): | |
k = pyDes.triple_des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m) | |
return k.decrypt(data) | |
def desencrypthex(key, data): | |
k = pyDes.des(codecs.decode(key, 'hex'), pad=None, padmode=pyDes.PAD_NORMAL) | |
e = k.encrypt(codecs.decode(data, 'hex')) | |
return codecs.encode(e, 'hex') | |
def tripledesencrypthex(key, data): | |
k = pyDes.triple_des(codecs.decode(key, 'hex'), pad=None, padmode=pyDes.PAD_NORMAL) | |
e1 = k.encrypt(codecs.decode(data, 'hex')) | |
return codecs.encode(e1, 'hex') | |
def DataNot(data): | |
r = [chr((~ord(a)) & 0xFF) for a in data] | |
return "".join(r) | |
def PadCardPhyNo(phyno): | |
r = '' | |
if len(phyno) < 8: | |
pad = "\x80\x00\x00\x00\x00\x00\x00\x00" | |
l = 8 - len(phyno) | |
r = phyno + pad[:l] | |
elif len(phyno) == 8: | |
r = phyno | |
else: | |
r = phyno[:8] | |
return r | |
def PadCardPhyNoHex(phyno): | |
return codecs.encode(PadCardPhyNo(codecs.decode(phyno, 'hex')), 'hex') | |
def PbocDeliveryKey(factor, key): | |
cipherdatanot = '' | |
cipherdata = PadCardPhyNo(factor) | |
print "factor is [%s]" % codecs.encode(cipherdata, 'hex') | |
# singledes delivery | |
if len(key) == 8: | |
k1 = desencrypt(key, cipherdata) | |
return k1 | |
elif len(key) == 16: | |
cipherdatanot = DataNot(cipherdata) | |
k1 = tripledesencrypt(key, cipherdata) | |
k2 = tripledesencrypt(key, cipherdatanot) | |
return k1 + k2 | |
else: | |
raise ValueError('key length error') | |
def PbocDeliveryKeyHex(factor, key): | |
f = codecs.decode(factor, 'hex') | |
k = codecs.decode(key, 'hex') | |
k1 = PbocDeliveryKey(f, k) | |
return codecs.encode(k1, 'hex') | |
def CalcMac3DES(data, initdata, key): | |
datalen = len(data) | |
k = pyDes.des(key[:8], pad=None, padmode=pyDes.PAD_NORMAL) | |
for i in range(datalen / 8): | |
m = [] | |
for j in range(len(initdata)): | |
m.append(chr(ord(initdata[j]) ^ ord(data[i * 8 + j]))) | |
initdata = "".join(m) | |
x = k.encrypt(initdata) | |
initdata = x | |
k1 = pyDes.des(key[8:], pad=None, padmode=pyDes.PAD_NORMAL) | |
n = k1.decrypt(initdata) | |
initdata = k.encrypt(n) | |
return initdata | |
def CalcMac3DESHex(data, initdata, key): | |
d = codecs.decode(data, 'hex') | |
id = codecs.decode(initdata, 'hex') | |
k = codecs.decode(key, 'hex') | |
k1 = CalcMac3DES(d, id, k) | |
return codecs.encode(k1, 'hex') | |
def CalcMacDES(data, initdata, key): | |
datalen = len(data) | |
k = pyDes.des(key, pad=None, padmode=pyDes.PAD_NORMAL) | |
for i in range(datalen / 8): | |
m = [] | |
for j in range(len(initdata)): | |
m.append(chr(ord(initdata[j]) ^ ord(data[i * 8 + j]))) | |
initdata = "".join(m) | |
x = k.encrypt(initdata) | |
initdata = x | |
return initdata | |
def CalcMacDESHex(data, initdata, key): | |
d = codecs.decode(data, 'hex') | |
id = codecs.decode(initdata, 'hex') | |
k = codecs.decode(key, 'hex') | |
k1 = CalcMacDES(d, id, k) | |
return codecs.encode(k1, 'hex') | |
def encrypt_m1key(inputkey): | |
statickey = codecs.decode('3230303530313331', 'hex') | |
key = codecs.decode(inputkey[:16], 'hex') | |
outkey = [] | |
for i in range(8): | |
t1 = ord(key[i]) | |
t2 = ord(statickey[i]) | |
t = ((~t1) ^ t2) & 0xFF | |
outkey.append(chr(t)) | |
return codecs.encode(''.join(outkey), 'hex') | |
def tlv_fetch_value(data): | |
datalen = len(data) | |
offset = 0 | |
while offset < datalen: | |
t = ord(data[offset]) | |
if t & 0x0F == 0x0F: | |
tag = data[offset:offset + 2] | |
offset += 2 | |
else: | |
tag = data[offset] | |
offset += 1 | |
t = ord(data[offset]) | |
if t & 0x80 == 0x80: | |
vl = t & 0x7F | |
vlen = 0 | |
for c in data[offset + 1:offset + 1 + vl]: | |
vlen = (vlen << 8) + ord(c) | |
offset += 1 + vl | |
else: | |
vlen = t & 0x7F | |
offset += 1 | |
if datalen - offset < vlen: | |
raise ValueError(u"data length Error, tag [%s]length[%d]" % ( | |
codecs.encode(tag, 'hex'), vlen)) | |
value = data[offset:offset + vlen] | |
offset += vlen | |
yield (tag, value,) | |
def tlv_fetch_value_hex(data): | |
for n, v in tlv_fetch_value(codecs.decode(data, 'hex')): | |
yield (codecs.encode(n, 'hex'), codecs.encode(v, 'hex')) | |
def tlv_parse_value(data): | |
""" | |
分析 tlv 格式的数据 | |
""" | |
result = {} | |
for n, v in tlv_fetch_value(data): | |
result.setdefault(n, v) | |
return result | |
def tlv_parse_value_hex(data): | |
""" | |
分析 tlv 格式的数据, data 是 hex 格式 | |
""" | |
result = {} | |
for n, v in tlv_fetch_value(codecs.decode(data, 'hex')): | |
result.setdefault(codecs.encode(n, 'hex'), codecs.encode(v, 'hex')) | |
return result | |
def tlv_fetch_define(data): | |
""" | |
分析 tlv 定义(不包括数据) | |
""" | |
datalen = len(data) | |
offset = 0 | |
while offset < datalen: | |
t = ord(data[offset]) | |
if t & 0x0F == 0x0F: | |
tag = data[offset:offset + 2] | |
offset += 2 | |
else: | |
tag = data[offset] | |
offset += 1 | |
t = ord(data[offset]) | |
if t & 0x80 == 0x80: | |
vl = t & 0x7F | |
vlen = 0 | |
for c in data[offset + 1:offset + 1 + vl]: | |
vlen = (vlen << 8) + ord(c) | |
offset += 1 + vl | |
else: | |
vlen = t & 0x7F | |
offset += 1 | |
yield (tag, vlen,) | |
def tlv_fetch_define_hex(data): | |
""" | |
分析 tlv 定义(不包括数据), data hex 格式 | |
""" | |
for n, l in tlv_fetch_define(codecs.decode(data, 'hex')): | |
yield (codecs.encode(n, 'hex'), l) | |
def tlv_parse_define(data): | |
""" | |
分析 tlv 定义(不包括数据) | |
""" | |
result = {} | |
for n, l in tlv_fetch_define(data): | |
result.setdefault(n, l) | |
return result | |
def tlv_parse_define_hex(data): | |
""" | |
分析 tlv 定义(不包括数据), data hex 格式 | |
""" | |
result = {} | |
for n, l in tlv_fetch_define(codecs.decode(data, 'hex')): | |
result.setdefault(codecs.encode(n, 'hex'), l) | |
return result | |
def extract_ec_data(data, tags): | |
offset = 0 | |
datalen = len(data) | |
for tag in tags: | |
tag_len = len(tag) | |
if offset + tag_len > datalen: | |
break | |
if data[offset:offset + tag_len] != tag: | |
raise KeyError(u"Tag [%s] not found", codecs.encode(tag, 'hex')) | |
offset += tag_len | |
t = ord(data[offset]) | |
if t & 0x80 == 0x80: | |
vl = t & 0x7F | |
vlen = 0 | |
for c in data[offset + 1:offset + 1 + vl]: | |
vlen = (vlen << 8) + ord(c) | |
offset += 1 + vl | |
else: | |
vlen = t & 0x7F | |
offset += 1 | |
if offset + vlen > datalen: | |
raise ValueError(u"data length error!tag[%s]length[%d]" % ( | |
codecs.encode(tag, 'hex'), vlen)) | |
value = data[offset:offset + vlen] | |
offset += vlen | |
yield (tag, value,) | |
def extract_ec_data_hex(data, tags): | |
t = [codecs.decode(a, 'hex') for a in tags] | |
for t, v in extract_ec_data(codecs.decode(data, 'hex'), t): | |
yield (codecs.encode(t, 'hex'), codecs.encode(v, 'hex'),) | |
def extract_ec_data_dict_hex(data, tags): | |
result = {} | |
for t, v in extract_ec_data_hex(data, tags): | |
result.setdefault(t, v) | |
return result |