def load(self, term, adf, apdu): apdu.selectAID(adf.aid) apdu.selectFID(adf.fid) pin = '888888' apdu.verifyPin(pin) assert apdu.sw == '9000' apdu.initForLoad(term.tsType == const.TTI_EP_LOAD, term.key.keyNo, term.tsAmount, term.id) CheckIf(apdu.sw == '9000') # Check response balance = apdu.res[:8] olCtr = apdu.res[8:12] #CheckIf(apdu.res[12:14] == term.key.) #CheckIf(apdu.res[14:16] == f. ) rnd = apdu.res[16:24] sesk = Algo_DES_Encryption_ECB(rnd + olCtr + '8000', term.key.keyValue) CheckIf(apdu.res[24:] == Algo_MAC( balance + term.tsAmount + term.tsType + term.id, '00' * 8, sesk)[:8]) # Genarate MAC2 mac2 = Algo_MAC(term.tsAmount + term.tsType + term.id + term.dateTime, '00' * 8, sesk)[:8] apdu.creditForLoad(term.dateTime, mac2) CheckIf(apdu.sw == '9000')
def cashWithDraw(self, term, adf, apdu): apdu.selectAID(adf.aid) keyf = adf.findEF('00') f = adf.findEF('01') pin = keyf.getKeyByType(const.KEY_TYPE_PIN) apdu.verifyPin(pin.keyValue) apdu.initForPurchase(term.tsType == const.TTI_EP_PURCHASE, term.key.keyNo, term.tsAmount, term.id) CheckIf(apdu.res[:8] == f.balance) CheckIf(apdu.res[8:12] == f.offCtr) CheckIf(apdu.res[12:18] == adf.overDrawLimit) rand = apdu.res[-8:] # Generate SESK sesk = Algo_DES_Encryption_ECB(rand + f.offCtr + term.tsCtr[-4:], term.key.keyValue) mac1 = Algo_MAC(term.tsAmount + term.tsType + term.id + term.dateTime, '00' * 8, sesk)[:8] apdu.debitForPurchase(term.tsCtr, term.dateTime, mac1) assert apdu.sw == '9000' CheckIf(apdu.res[8:] == Algo_MAC(term.tsAmount, '00' * 8, sesk)[:8]) tacKey = keyf.getKeyByType(const.KEY_TYPE_TAC) sesk = Algo_Xor(tacKey.keyValue[:16], tacKey.keyValue[16:]) newBlc = '%08X' % (int(f.balance, 16) - int(term.tsAmount, 16)) tac = Algo_MAC( term.tsAmount + term.tsType + term.id + term.tsCtr + term.dateTime, '00' * 8, sesk)[:8] CheckIf(apdu.res[:8] == tac) f.balance = newBlc f.offCtr = '%04X' % (int(f.offCtr, 16) + 1) adf.saveTransactionLog(term, f)
def _CalcMac(type, res): if type == 'load': balance = res[:8] olCtr = res[8:12] rnd = res[16:24] sesk = Algo_DES_Encryption_ECB(rnd + olCtr + '8000', d['LOAD_KEY']) assert (res[24:] == Algo_MAC( balance + d['TS_AMT'] + const.TTI_EP_LOAD + '112233445566', '00' * 8, sesk)[:8]) # Genarate MAC2 mac2 = Algo_MAC( d['TS_AMT'] + const.TTI_EP_LOAD + '112233445566' + d['DATE'], '00' * 8, sesk)[:8] return mac2
def applicationBlock(self, isTemporary, rand, key): if isTemporary: cmd = '841E000004' else: cmd = '841E000104' self.apdu = cmd + Algo_MAC(cmd, rand, key)[:8] self.postProcess()
def readBianry(self, sfi, offset, le, key='', iv=''): if key != '': cmd = '04B0' + '%02X' % (int(sfi, 16) + 0x80) + offset + '04' self.apdu = cmd + Algo_MAC(cmd, iv, key)[:8] else: self.apdu = '00B0' + '%02X' % (int(sfi, 16) + 0x80) + offset + le self.postProcess()
def purchase(self, term, adf, apdu): apdu.selectAID(adf.aid) apdu.selectFID(adf.fid) apdu.initForPurchase(term.tsType == const.TTI_EP_PURCHASE, term.key.keyNo, term.tsAmount, term.id) balance = apdu.res[:8] offCtr = apdu.res[8:12] rand = apdu.res[-8:] # Generate SESK sesk = Algo_DES_Encryption_ECB(rand + offCtr + term.tsCtr[-4:], term.key.keyValue) mac1 = Algo_MAC(term.tsAmount + term.tsType + term.id + term.dateTime, '00' * 8, sesk)[:8] apdu.debitForPurchase(term.tsCtr, term.dateTime, mac1) assert apdu.sw == '9000' CheckIf(apdu.res[8:] == Algo_MAC(term.tsAmount, '00' * 8, sesk)[:8])
def reloadPin(self, newPin, key): if len(newPin) % 2 != 0: newPin += 'F' key = Algo_Xor(key[:16], key[16:]) cmd = '805E0000' + LV(newPin + Algo_MAC(newPin, '00' * 8, key)[:8]) self.apdu = cmd self.postProcess()
def readRecord(self, p1, sfi, le, mode=4, key='', iv=''): # mode 4 as No,mode 0 as tag if key != '': cmd = '04B2' + p1 + '%02X' % (int(sfi, 16) * 8 + mode) + '04' self.apdu = cmd + Algo_MAC(cmd, iv, key)[:8] else: self.apdu = '00B2' + p1 + '%02X' % (int(sfi, 16) * 8 + mode) + le self.postProcess()
def appendRecord(self, sfi, data, key='', iv=''): if key == '': cmd = '00E200' + '%02X' % (int(sfi, 16) * 8) + LV(data) else: cmd = '04E200' + '%02X' % (int(sfi, 16) * 8) + '%02X' % (len(data) / 2 + 4) + data cmd = cmd + Algo_MAC(cmd, iv, key)[:8] self.apdu = cmd self.postProcess()
def updateBinary(self, sfi, offset, data, key='', iv=''): if key == '': cmd = '00D6' + '%02X' % (int(sfi, 16) + 0x80) + offset + LV(data) else: cmd = '04D6' + '%02X' % (int(sfi, 16) + 0x80) + offset + '%02X' % ( len(data) / 2 + 4) + data cmd = cmd + Algo_MAC(cmd, iv, key)[:8] self.apdu = cmd self.postProcess()
def cappPurchase(self, term, adf, apdu): apdu.selectAID(adf.aid) keyf = adf.findEF('00') f = adf.findEF('02') pin = keyf.getKeyByType(const.KEY_TYPE_PIN) apdu.verifyPin(pin.keyValue) apdu.initializeForCappPurchase(term.key.keyNo, term.tsAmount, term.id) CheckIf(apdu.res[:8] == f.balance) CheckIf(apdu.res[8:12] == f.offCtr) CheckIf(apdu.res[12:18] == adf.overDrawLimit) rand = apdu.res[-8:] # Update capp datacache for k, v in term.capp.items(): sfi = k[:2] tag = k[2:4] apdu.updateCappDataCache(tag, sfi, v) assert apdu.sw == '9000' ef = adf.findEF(sfi) ef.updateRecordByTag(v) # Generate SESK sesk = Algo_DES_Encryption_ECB(rand + f.offCtr + term.tsCtr[-4:], term.key.keyValue) mac1 = Algo_MAC(term.tsAmount + term.tsType + term.id + term.dateTime, '00' * 8, sesk)[:8] apdu.debitForPurchase(term.tsCtr, term.dateTime, mac1) assert apdu.sw == '9000' CheckIf(apdu.res[8:] == Algo_MAC(term.tsAmount, '00' * 8, sesk)[:8]) tacKey = keyf.getKeyByType(const.KEY_TYPE_TAC) tacSesk = Algo_Xor(tacKey.keyValue[:16], tacKey.keyValue[16:]) newBlc = '%08X' % (int(f.balance, 16) - int(term.tsAmount, 16)) tac = Algo_MAC( term.tsAmount + term.tsType + term.id + term.tsCtr + term.dateTime, '00' * 8, tacSesk)[:8] CheckIf(apdu.res[:8] == tac) mac2 = Algo_MAC(term.tsAmount, '00' * 8, sesk)[:8] CheckIf(apdu.res[8:] == mac2) f.balance = newBlc f.offCtr = '%04X' % (int(f.offCtr, 16) + 1) adf.tsProve = {f.offCtr + term.tsType: mac2 + tac} adf.saveTransactionLog(term, f)
def unblockPin(self, pin, randData, key): if len(pin) % 2 != 0: pin += 'F' pin = LV(pin) + '80' pin += '0' * (16 - len(pin)) pin = Algo_DES_Encryption_ECB(pin, key) cmd = '842400000C' + pin cmd = cmd + Algo_MAC(cmd, randData, key)[:8] self.apdu = cmd self.postProcess()
def updateRecord(self, p1, sfi, data, mode='04', key='', iv=''): # mode 4 as No # mode 0 as tag` p2 = '%02X' % ((int(sfi, 16) << 3) + int(mode, 16)) if key == '': cmd = '00DC' + p1 + p2 + LV(data) else: cmd = '04DC' + p1 + p2 + '%02X' % (len(data) / 2 + 4) + data cmd = cmd + Algo_MAC(cmd, iv, key)[:8] self.apdu = cmd self.postProcess()
def writeKey(self, p1, p2, keyData, key='', iv=''): if key == '': cmd = '80D4' + p1 + p2 + LV(keyData) else: keyData = LV(keyData) + '80' while len(keyData) % 16 != 0: keyData += '00' keyData = Algo_DES_Encryption_ECB(keyData, key) cmd = '84D4' + p1 + p2 + '%02X' % (len(keyData) / 2 + 4) + keyData cmd = cmd + Algo_MAC(cmd, iv, key)[:8] self.apdu = cmd self.postProcess()
d['key_value'] = e cmdList.append(d) i = i+1 def _input(self): f = open('keyBase','r') l = f.readlines() f.close() return [e.replace('\n','') for e in l] def _output(self): f = open(self.fn+'.json','w') f.seek(0) s = JSONEncoder().encode( self.dCmdFlow) f.write(s) f.close() ''' #sesk = Algo_DES_Encryption_ECB(rand + offCtr + term.tsCtr[-4:], term.key.keyValue) #mac1 = Algo_MAC(term.tsAmount + term.tsType + term.id + term.dateTime,'00' * 8,sesk)[:8] k = '0BA5B6D33FEC6DD73A5AA6CF81E818C7' rnd = '110F960F' ctr = '0013' sesk = Algo_DES_Encryption_ECB(rnd + ctr + '3344', k) mac = Algo_MAC('0000FFED0611223344556620160115162449677', '00' * 8, sesk)[:8] print sesk print mac #mac2 = Algo_MAC('8877665544332211', '00' * 8, '11223344556677881122334455667700')
def cardBlock(self, rand, key): cmd = '8416000004' cmd = cmd + Algo_MAC(cmd, rand, key)[:8] self.apdu = cmd self.postProcess()
def applicationUnblock(self, rand, key): cmd = '8418000004' cmd = cmd + Algo_MAC(cmd, rand, key)[:8] self.apdu = cmd self.postProcess()