Пример #1
0
def command_KQ(cmdObj):
    """ ARQC (or TC/AAC) Verification and/or ARPC Generation. """
    """ Command Pattern:
        request: Message header + 'KQ' + Mode Flag + Scheme ID + MK-AC + Primary Account Number + Application Transaction Counter + Unpredictable Number + Transaction Data Length + Transaction Data + Delimiter(;) + ARQC + Authorization Response Code + End message delimiter + Message Trailer
        response: Message header + 'KR' + Error code + ARPC + End Message delimiter + Message Trailer
    """
    
    if len(cmdObj.MK_AC.value) != 32:
        raise ValueError('MK-AC length error')
    if cmdObj.MK_AC.scheme == '':
        MK_AC = decryptKeyUnderLMK('MK-AC', unhexlify(cmdObj.MK_AC.value))
    else:
        MK_AC = decryptKeyUnderLMK('MK-AC', unhexlify(cmdObj.MK_AC.value), cmdObj.MK_AC.scheme)
    # Transaction Data最后有一个分隔符
    sessionKey = icSessionKey(icKeyDerivation(MK_AC, hexlify(cmdObj.PAN.value), ''), cmdObj.ATC.value)
    resp_cd = '00'
    if cmdObj.ModeFlag.value == '0' or cmdObj.ModeFlag.value == '1':
        block = padDataBlock(cmdObj.TransactionData.value)
        ac = calcMAC(sessionKey, block, '\x00'*8)
        if ac == cmdObj.ARQC.value:
            resp_cd = '00'
        else:
            resp_cd = '01'

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable(resp_cd)

    if cmdObj.ModeFlag.value == '1' or cmdObj.ModeFlag.value == '2':
        k = pyDes.triple_des(sessionKey)
        arpc = k.encrypt(blockXOR(cmdObj.ARQC.value, cmdObj.ARC.value+'\x00\x00\x00\x00\x00\x00'))
        respObj.ARPC = DataVariable(arpc)
    else:
        respObj.ARPC = DataVariable('')

    return respObj
Пример #2
0
def command_DA(cmdObj):
    """ Verify a PIN from a local ATM (or PIN pad etc.) using the IBM 3624 method. """
    """ Command Pattern:
	    request: Message header + 'EA' + TPK + PVK + Max PIN Length + PIN Block + PIN Block Format Code + Check length + Account Number + Decimalization Table + PIN Validation data + Offset + End message delimiter + Message Trailer
	    response: Message header + 'EB' + Error code + End Message delimiter + Message Trailer
	"""

    TPK = decryptKeyUnderLMK('TPK', unhexlify(cmdObj.TPK.value),
                             cmdObj.TPK.scheme)
    tpk = KeyScheme(TPK)
    pinblock = tpk.decrypt(unhexlify(cmdObj.PINBlock.value))
    enteredPIN = extractPINFromPINBlock(pinblock, cmdObj.AccountNumber.value,
                                        cmdObj.PINBlockFormatCode.value)
    if (len(enterdPIN) > string.atoi(cmdObj.MaxPINLength.value)):
        raise ValueError('invalid pin length')

    PVK = decryptKeyUnderLMK('PVK', unhexlify(cmdObj.PVK.value),
                             cmdObj.PVK.scheme)
    derivedPIN = genPINUsingIBMMetheod(PVK, cmdObj.AccountNumber.value,
                                       cmdObj.PINValidationData.value,
                                       cmdObj.DecimalizationTable.value)
    print "PIN=", derivedPIN
    finalPIN = genFinalPIN(derivedPIN, cmdObj.Offset.value)

    respObj = CommandObj()
    if (enteredPIN == finalPIN):
        respObj.ResponseCode = DataVariable('00')
    else:
        respObj.ResponseCode = DataVariable('01')
    return respObj
Пример #3
0
def command_A0(cmdObj):
    """ To generate a key and optionally encrypt key under ZMK for transmission."""
    """ Command Pattern:
	    request: Message header + 'A0' + Mode + Key Type + Key Scheme LMK + ZMK + Key Scheme ZMK + Atalla Variant + End message delimiter + Message Trailer
	    response: Message header + 'A1' + Error code + Key under LMK + Key under ZMK + Check Value + End Message delimiter + Message Trailer
	"""

    clearKey = genRandomKey(Configure.CFG_KEY_LENGTH / 2)
    keyType = Configure.KeyTypeTable[cmdObj.KeyType.value]
    cipherKeyUnderLMK = encryptKeyUnderLMK(keyType, clearKey,
                                           cmdObj.KeySchemeLMK.value)

    if cmdObj.Mode.value == '1':
        ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                                 cmdObj.ZMK.scheme)
        zmkScheme = KeyScheme(ZMK, cmdObj.KeySchemeZMK.value)
        cipherKeyUnderZMK = zmkScheme.encrypt(clearKey)

    key = KeyScheme(clearKey)
    kcv = hexlify(key.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.KeyUnderLMK = KeyVariable(
        hexlify(cipherKeyUnderLMK).upper(), cmdObj.KeySchemeLMK.value)
    if cmdObj.Mode.value == '1':
        respObj.KeyUnderZMK = KeyVariable(
            hexlify(cipherKeyUnderZMK).upper(), cmdObj.KeySchemeZMK.value)
    else:
        respObj.KeyUnderZMK = DataVariable('')
    respObj.CheckValue = DataVariable(kcv[:6])
    return respObj
Пример #4
0
def command_IA(cmdObj):
    """ Generate a random PIN key and return it to the Host encrypted under a ZMK
		for transmission to another party and under the LMK for storage on the Host
		database."""
    """ Command Pattern:
	    request: Message header + 'IA' + ZMK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
	    response: Message header + 'IB' + Error code + ZPK under ZMK + ZPK under LMK + Check Value + End Message delimiter + Message Trailer
	"""

    (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj)
    clearZPK = genRandomKey(Configure.CFG_KEY_LENGTH / 2)
    ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                             cmdObj.ZMK.scheme)
    cipherZPKUnderLMK = encryptKeyUnderLMK('ZPK', clearZPK, schemeLMK)
    zmkScheme = KeyScheme(ZMK, schemeZMK)
    cipherZPKUnderZMK = zmkScheme.encrypt(clearZPK)

    zpk = KeyScheme(clearZPK)
    kcv = hexlify(zpk.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.ZPKUnderZMK = KeyVariable(
        hexlify(cipherZPKUnderZMK).upper(), schemeZMK)
    respObj.ZPKUnderLMK = KeyVariable(
        hexlify(cipherZPKUnderLMK).upper(), schemeLMK)
    respObj.CheckValue = DataVariable(kcv[:kcvLength])
    return respObj
Пример #5
0
def command_MQ(cmdObj):
    """ Generate a MAC (MAB) for a large message. """
    """ Command Pattern:
        request: Message header + 'MQ' + Message Block Number + TAK + IV + Message Length + Message Block + End message delimiter + Message Trailer
        response: Message header + 'MR' + Error code + MAB + End Message delimiter + Message Trailer
    """

    TAK = decryptKeyUnderLMK('TAK', unhexlify(cmdObj.TAK.value),
                             cmdObj.TAK.scheme)

    if (cmdObj.MessageBlockNumber.value == '0'):  # The only block.
        mac = calcMAC(TAK, cmdObj.MessageBlock.value, "\0\0\0\0\0\0\0\0")
    elif (cmdObj.MessageBlockNumber.value == '1'):  # The first block.
        mac = calcMAC(TAK, cmdObj.MessageBlock.value, "\0\0\0\0\0\0\0\0")
    elif (cmdObj.MessageBlockNumber.value == '2'):  # A middle block.
        mac = calcMAC(TAK, cmdObj.MessageBlock.value,
                      unhexlify(cmdObj.IV.value))
    elif (cmdObj.MessageBlockNumber.value == '3'):  # The last block.
        mac = calcMAC(TAK, cmdObj.MessageBlock.value,
                      unhexlify(cmdObj.IV.value))
    else:
        raise ValueError('invalid message block number [' +
                         cmdObj.MessageBlockNumber.value + ']')

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.MAB = DataVariable(string.upper(hexlify(mac)))
    return respObj
Пример #6
0
def command_FE(cmdObj):
    """ Translate a TMK, TPK or PVK from encryption under the LMK to encryption
		under a ZMK. """
    """ Command Pattern:
	    request: Message header + 'FE' + ZMK + TMK_TPK_PVK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
	    response: Message header + 'FF' + Error code + TMK_TPK_PVK + Check Value + End Message delimiter + Message Trailer
	"""

    (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj)
    ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                             cmdObj.ZMK.scheme)
    clearTMK_TPK_PVK = decryptKeyUnderLMK('PVK',
                                          unhexlify(cmdObj.TMK_TPK_PVK.value),
                                          cmdObj.TMK_TPK_PVK.scheme)
    zmkScheme = KeyScheme(ZMK, schemeZMK)
    cipherTMK_TPK_PVK = zmkScheme.encrypt(clearTMK_TPK_PVK)

    tmk_tpk_pvk = KeyScheme(clearTMK_TPK_PVK)
    kcv = hexlify(tmk_tpk_pvk.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.TMK_TPK_PVK = KeyVariable(
        hexlify(cipherTMK_TPK_PVK).upper(), schemeZMK)
    respObj.CheckValue = DataVariable(kcv[:kcvLength])
    return respObj
Пример #7
0
def command_JE(cmdObj):
    """ Translate a PIN from encryption under a ZPK to encryption under the LMK. """
    """ Command Pattern:
        request: Message header + 'JE' + ZPK + PIN Block + PIN Block Format Code + Account Number + End message delimiter + Message Trailer
        response: Message header + 'JF' + Error code + PIN + End Message delimiter + Message Trailer
    """

    respObj = CommandObj()

    ZPK = decryptKeyUnderLMK('ZPK', unhexlify(cmdObj.ZPK.value),
                             cmdObj.ZPK.scheme)
    zpk = KeyScheme(ZPK)
    pinblock = zpk.decrypt(unhexlify(cmdObj.PINBlock.value))
    (clearPIN, rslt) = extrackPINFromPINBlock(pinblock,
                                              cmdObj.AccountNumber.value,
                                              cmdObj.PINBlockFormatCode.value)
    if rslt != '00':
        respObj.ResponseCode = DataVariable(rslt)
        return respObj
    print "clearPIN=", clearPIN
    if (len(clearPIN) < 4) or (len(clearPIN) > 12):
        respObj.ResponseCode = DataVariable('24')
        return respObj
    cipherPIN = encryptPINUnderLMK(clearPIN, cmdObj.AccountNumber.value)

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.PIN = DataVariable(cipherPIN)
    return respObj
Пример #8
0
def command_KU(cmdObj):
    """ Generate Secure Message with Integrity and Optional Confidentiality and PIN Change """
    """ Command Pattern:
        request: Message header + 'KU' + Mode Flag + Scheme ID + MK-SMI + Primary Account Number + Integrity Session Data + Plaintext Data Length + Plaintext Data + Delimiter(;) + MK-SMC + TK + Confidentiality Session Data + Offset + Cipher Data Length + Cipher Data + Delimiter(;) + Source PIN Encryption Key Type + Source PIN Encryption Key + Source PIN Block Format + Destination PIN Block Format + Primary Account Number + MK-AC + End message delimiter + Message Trailer
        response: Message header + 'KV' + Error code + ARPC + End Message delimiter + Message Trailer
    """
    
    if len(cmdObj.MK_SMI.value) != 32:
        raise ValueError('MK-SMI length error')
    if cmdObj.MK_SMI.scheme == '':
        MK_SMI = decryptKeyUnderLMK('MK-SMI', unhexlify(cmdObj.MK_SMI.value))
    else:
        MK_SMI = decryptKeyUnderLMK('MK-SMI', unhexlify(cmdObj.MK_SMI.value), cmdObj.MK_SMI.scheme)
    # Plain Data最后有一个分隔符
    atc = cmdObj.IntegritySessionData.value[-2:]
    sessionKey = icSessionKey(icKeyDerivation(MK_SMI, hexlify(cmdObj.PAN.value), ''), atc)
    block = padDataBlock(cmdObj.PlainData.value)
    mac = calcMAC(sessionKey, block, '\x00'*8)

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')

    respObj.MAC = DataVariable(mac)

    return respObj
Пример #9
0
def command_HA(cmdObj):
    """ Generate a random key, and encrypt it under a TMK (TPK or PVK) and under
		LMK pair 16-17. """
    """ Command Pattern:
	    request: Message header + 'HA' + TMK + Atalla Variant + Delimiter + Key Scheme TMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
	    response: Message header + 'HB' + Error code + ZPK under ZMK + ZPK under LMK + Check Value + End Message delimiter + Message Trailer
	"""

    (schemeTMK, schemeLMK, kcvLength) = extractTMKSchemeAndKcvLength(cmdObj)
    clearZPK = genRandomKey(Configure.CFG_KEY_LENGTH / 2)
    TMK = decryptKeyUnderLMK('TMK', unhexlify(cmdObj.TMK.value),
                             cmdObj.TMK.scheme)
    cipherTAKUnderLMK = encryptKeyUnderLMK('TAK', clearTAK, schemeLMK)
    tmkScheme = KeyScheme(TMK, schemeTMK)
    cipherTAKUnderTMK = tmkScheme.encrypt(clearTAK)

    tak = KeyScheme(clearTAK)
    kcv = hexlify(tak.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.TAKUnderTMK = KeyVariable(
        hexlify(cipherTAKUnderTMK).upper(), schemeTMK)
    respObj.TAKUnderLMK = KeyVariable(
        hexlify(cipherTAKUnderLMK).upper(), schemeLMK)
    respObj.CheckValue = DataVariable(kcv[:kcvLength])
    return respObj
Пример #10
0
def command_CC(cmdObj):
    """ Translate a PIN block from encryption under one ZPK to encryption under
        another ZPK and from one format to another. If the same ZPK is defined, only
        the PIN block is translated, and if the same PIN block format is defined, only
        the key is translated. """
    """ Command Pattern:
        request: Message header + 'CC' + Source ZPK + Destination ZPK + Maximum PIN Length + Source PIN Block + Source PIN Block Format + Destination PIN Block Format + Account Number + End message delimiter + Message Trailer
        response: Message header + 'CD' + Error code + PIN Length + Destination PIN Block + Destination PIN Block Format + End Message delimiter + Message Trailer
    """

    SourceZPK = decryptKeyUnderLMK('ZPK', unhexlify(cmdObj.SourceZPK.value),
                                   cmdObj.SourceZPK.scheme)
    src_zpk = KeyScheme(SourceZPK)
    DestinationZPK = decryptKeyUnderLMK('ZPK',
                                        unhexlify(cmdObj.DestinationZPK.value),
                                        cmdObj.DestinationZPK.scheme)
    dst_zpk = KeyScheme(DestinationZPK)

    src_pinblock = src_zpk.decrypt(unhexlify(cmdObj.SourcePINBlock.value))
    (clearPIN, rlt) = extrackPINFromPINBlock(src_pinblock,
                                             cmdObj.AccountNumber.value,
                                             cmdObj.SourcePINBlockFormat.value)
    print "clearPIN=" + clearPIN
    dst_pinblock = genPINBlock(clearPIN, cmdObj.AccountNumber.value,
                               cmdObj.DestinationPINBlockFormat.value)
    dst_pinblock = hexlify(dst_zpk.encrypt(dst_pinblock))

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.PINLength = DataVariable("%02d" % len(clearPIN))
    respObj.DestinationPINBlock = DataVariable(string.upper(dst_pinblock))
    respObj.DestinationPINBlockFormat = DataVariable(
        cmdObj.DestinationPINBlockFormat.value)
    return respObj
Пример #11
0
def command_FI(cmdObj):
    """ Generate a ZEK or ZAK. """
    """ Command Pattern:
	    request: Message header + 'FI' + Flag + ZMK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
	    response: Message header + 'FI' + Error code + ZEK/ZAK under ZMK + ZEK/ZAK under LMK + Check Value + End Message delimiter + Message Trailer
	"""

    if cmdObj.Flag == '0':
        keyType = 'ZEK'
    elif cmdObj.Flag == '1':
        keyType = 'ZAK'
    else:
        raise ValueError('ZEK/ZAK Flag error')

    (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj)
    clearZEK_ZAK = genRandomKey(Configure.CFG_KEY_LENGTH / 2)
    ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                             cmdObj.ZMK.scheme)
    cipherKeyUnderLMK = encryptKeyUnderLMK(keyType, clearZEK_ZAK, schemeLMK)
    zmkScheme = KeyScheme(ZMK, schemeZMK)
    cipherKeyUnderZMK = zmkScheme.encrypt(clearZEK_ZAK)

    zek_zak = KeyScheme(clearZEK_ZAK)
    kcv = hexlify(zek_zak.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.ZEKZAKUnderZMK = KeyVariable(
        hexlify(cipherKeyUnderZMK).upper(), schemeZMK)
    respObj.ZEKZAKUnderLMK = KeyVariable(
        hexlify(cipherKeyUnderLMK).upper(), schemeLMK)
    respObj.CheckValue = DataVariable(kcv[:kcvLength])
    return respObj
Пример #12
0
def command_FG(cmdObj):
    """ Generate a random PIN key and return it to the Host encrypted under a ZMK
		for transmission to another party and under the LMK for storage on the Host
		database."""
    """ Command Pattern:
	    request: Message header + 'FG' + ZMK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
	    response: Message header + 'FH' + Error code + first PVK under ZMK + second PVK under LMK + Check Value + End Message delimiter + Message Trailer
	"""

    (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj)
    clearPVK1 = genRandomKey(Configure.CFG_KEY_LENGTH / 2)
    clearPVK2 = genRandomKey(Configure.CFG_KEY_LENGTH / 2)
    ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                             cmdObj.ZMK.scheme)
    cipherPVKUnderLMK = encryptKeyUnderLMK('PVK', clearPVK2, schemeLMK)
    zmkScheme = KeyScheme(ZMK, schemeZMK)
    cipherPVKUnderZMK = zmkScheme.encrypt(clearPVK1)

    pvk1 = KeyScheme(clearPVK1)
    kcv = hexlify(pvk1.encrypt("\0\0\0\0\0\0\0\0")).upper()
    pvk2 = KeyScheme(clearPVK2)
    kcv = hexlify(pvk2.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.PVKUnderZMK = KeyVariable(
        hexlify(cipherPVKUnderZMK).upper(), schemeZMK)
    respObj.PVKUnderLMK = KeyVariable(
        hexlify(cipherPVKUnderLMK).upper(), schemeLMK)
    if (kcvLength == Configure.CFG_KCV_LENGTH):
        respObj.CheckValue = DataVariable(kcv1 + kcv2)
    else:
        respObj.CheckValue = DataVariable(kcv1[:kcvLength])
    return respObj
Пример #13
0
def command_CY(cmdObj):
	""" Verify a VISA CVV. """
	""" Command Pattern:
	    request: Message header + 'CW' + CVK_A + CVK_B + CVV + Primary Account Number + Delimiter(;) + Expiration Date + Service Code + End message delimiter + Message Trailer
	    response: Message header + 'CX' + Error code + CVV + End Message delimiter + Message Trailer
	"""
	
	if len(cmdObj.CVK_AB.value) != 32:
		raise ValueError('CVK length error')
	if cmdObj.CVK_AB.scheme == '':
		CVK_A = decryptKeyUnderLMK('CVK', unhexlify(cmdObj.CVK_AB.value[:16]))
		CVK_B = decryptKeyUnderLMK('CVK', unhexlify(cmdObj.CVK_AB.value[16:]))
	else:
		CVK = decryptKeyUnderLMK('CVK', unhexlify(cmdObj.CVK_AB.value), cmdObj.CVK_AB.scheme)
		CVK_A = CVK[:8]
		CVK_B = CVK[8:]
	# Primary Account Number最后有一个分隔符
	CVV = genCVV(cmdObj.PrimaryAccountNumber.value[:-1], cmdObj.ExpirationDate.value, cmdObj.ServiceCode.value, CVK_A, CVK_B)
	
	respObj = CommandObj()
	if (CVV == cmdObj.CVV.value):
		respObj.ResponseCode = DataVariable('00')
	else:
		respObj.ResponseCode = DataVariable('01')
	return respObj
Пример #14
0
def command_NG(cmdObj):
	""" Decrypted an encrypted PIN and return a reference number. """
	""" Command Pattern:
	    request: Message header + 'NG' + Account Number + PIN + End message delimiter + Message Trailer
	    response: Message header + 'NH' + Error code + PIN + End Message delimiter + Message Trailer
	"""

	PIN = decryptPINUnderLMK(cmdObj.PIN.value, cmdObj.AccountNumber.value)
	
	respObj = CommandObj()
	respObj.ResponseCode = DataVariable('00')
	respObj.PIN = DataVariable(PIN)
	return respObj
Пример #15
0
def command_BA(cmdObj):
    """ Encrypt a clear text PIN. """
    """ Command Pattern:
	    request: Message header + 'NG' + PIN + Account Number + End message delimiter + Message Trailer
	    response: Message header + 'NH' + Error code + PIN + End Message delimiter + Message Trailer
	"""

    PIN = encryptPINUnderLMK(cmdObj.PIN.value, cmdObj.AccountNumber.value)

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.PIN = DataVariable(PIN)
    return respObj
Пример #16
0
def command_MS(cmdObj):
    """ To generate a MAB for a large message using either a TAK or a ZAK. If the
        key is single length use ANSI X9.9 MAC generation or if the key is double
        length use ANSI X9.19 MAC generation. """
    """ Command Pattern:
        request: Message header + 'MS' + Message Block Number + Key Type + Key Length + Message Length + Key + IV + Message Length + Message Block + End message delimiter + Message Trailer
        response: Message header + 'MT' + Error code + MAB + End Message delimiter + Message Trailer
    """

    if cmdObj.KeyType.value == '0':
        KeyType = 'TAK'
    elif cmdObj.KeyType.value == '1':
        KeyType = 'ZAK'
    else:
        raise ValueError('invalid key type [' + cmdObj.KeyType.value + ']')
    KEY = decryptKeyUnderLMK(KeyType, unhexlify(cmdObj.Key.value),
                             cmdObj.Key.scheme)

    if cmdObj.KeyLength.value == '0':
        keyLength = 8
    elif cmdObj.KeyLength.value == '1':
        keyLength = 16
    else:
        raise ValueError('invalid key length [' + cmdObj.KeyLength.value + ']')
    if len(KEY) != keyLength:
        raise ValueError('key length error')

    if cmdObj.MessageType.value == '0':
        messageBlock = cmdObj.MessageBlock.value
    elif cmdObj.MessageType.value == '1':
        messageBlock = unhexlify(cmdObj.MessageBlock.value)
    else:
        raise ValueError('invalid message type [' + cmdObj.MessageType.value +
                         ']')

    if (cmdObj.MessageBlockNumber.value == '0'):  # The only block.
        mac = calcMAC(KEY, messageBlock, "\0\0\0\0\0\0\0\0")
    elif (cmdObj.MessageBlockNumber.value == '1'):  # The first block.
        mac = calcMAC(KEY, messageBlock, "\0\0\0\0\0\0\0\0")
    elif (cmdObj.MessageBlockNumber.value == '2'):  # A middle block.
        mac = calcMAC(KEY, messageBlock, unhexlify(cmdObj.IV.value))
    elif (cmdObj.MessageBlockNumber.value == '3'):  # The last block.
        mac = calcMAC(KEY, messageBlock, unhexlify(cmdObj.IV.value))
    else:
        raise ValueError('invalid message block number [' +
                         cmdObj.MessageBlockNumber.value + ']')

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.MAB = DataVariable(string.upper(hexlify(mac)))
    return respObj
Пример #17
0
def command_MA(cmdObj):
    """ Generate a MAC on given data. """
    """ Command Pattern:
        request: Message header + 'MA' + TAK + Data + End message delimiter + Message Trailer
        response: Message header + 'MB' + Error code + MAC + End Message delimiter + Message Trailer
    """
    TAK = decryptKeyUnderLMK('TAK', unhexlify(cmdObj.TAK.value),
                             cmdObj.TAK.scheme)
    mac = calcMAC(TAK, cmdObj.Data.value, "\0\0\0\0\0\0\0\0")

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.MAC = DataVariable(string.upper(hexlify(mac))[:8])
    return respObj
Пример #18
0
def command_EE(cmdObj):
	""" Derive a PIN Using IBM Method """
	""" Command Pattern:
	    request: Message header + 'EE' + PVK + Offset + Check length + Account Number + Decimalization Table + PIN Validation data + End message delimiter + Message Trailer
	    response: Message header + 'EF' + Error code + PIN + End Message delimiter + Message Trailer
	"""
	PVK = decryptKeyUnderLMK('PVK', unhexlify(cmdObj.PVK.value), cmdObj.PVK.scheme)
	PIN = genPINUsingIBMMetheod(PVK, cmdObj.AccountNumber.value, cmdObj.PINValidationData.value, cmdObj.DecimalizationTable.value)
	finalPIN = genFinalPIN(PIN, cmdObj.Offset.value)
	cypherPIN = encryptPINUnderLMK(finalPIN, cmdObj.AccountNumber.value)
	
	respObj = CommandObj()
	respObj.ResponseCode = DataVariable('00')
	respObj.PIN = DataVariable(cypherPIN)
	return respObj
Пример #19
0
def command_JC(cmdObj):
	""" Translate a PIN from encryption under a TPK to encryption under the LMK. """
	""" Command Pattern:
	    request: Message header + 'JC' + TPK + PIN Block + PIN Block Format Code + Account Number + End message delimiter + Message Trailer
	    response: Message header + 'JD' + Error code + PIN + End Message delimiter + Message Trailer
	"""
	
	TPK = decryptKeyUnderLMK('TPK', unhexlify(cmdObj.TPK.value), cmdObj.TPK.scheme)
	tpk = KeyScheme(TPK)
	pinblock = tpk.decrypt(unhexlify(cmdObj.PINBlock.value))
	clearPIN = extrackPINFromPINBlock(pinblock, cmdObj.AccountNumber.value, cmdObj.PINBlockFormatCode.value)
	cipherPIN = encryptPINUnderLMK(clearPIN, cmdObj.AccountNumber.value)	
	
	respObj = CommandObj()
	respObj.ResponseCode = DataVariable('00')
	respObj.PIN = DataVariable(cipherPIN)
	return respObj
Пример #20
0
def command_MC(cmdObj):
    """ Verify a MAC and. """
    """ Command Pattern:
        request: Message header + 'MC' + TAK + MAC + Data + End message delimiter + Message Trailer
        response: Message header + 'MD' + Error code + End Message delimiter + Message Trailer
    """
    TAK = decryptKeyUnderLMK('TAK', unhexlify(cmdObj.TAK.value),
                             cmdObj.TAK.scheme)
    mac = calcMAC(TAK, cmdObj.Data.value, "\0\0\0\0\0\0\0\0")
    finalMAC = string.upper(hexlify(mac))[:8]

    respObj = CommandObj()
    if cmdObj.MAC.value == finalMAC:
        respObj.ResponseCode = DataVariable('00')
    else:  # УÑéʧ°Ü
        respObj.ResponseCode = DataVariable('01')
    return respObj
Пример #21
0
def command_DE(cmdObj):
    """ Generate a PIN offset using the IBM method. """
    """ Command Pattern:
	    request: Message header + 'EE' + PVK + PIN + Check length + Account Number + Decimalization Table + PIN Validation data + End message delimiter + Message Trailer
	    response: Message header + 'EF' + Error code + Offset + End Message delimiter + Message Trailer
	"""
    PVK = decryptKeyUnderLMK('PVK', unhexlify(cmdObj.PVK.value),
                             cmdObj.PVK.scheme)
    PIN = genPINUsingIBMMetheod(PVK, cmdObj.AccountNumber.value,
                                cmdObj.PINValidationData.value,
                                cmdObj.DecimalizationTable.value)
    print "PIN=", PIN
    clearPIN = decryptPINUnderLMK(cmdObj.PIN.value, cmdObj.AccountNumber.value)
    Offset = genOffset(PIN, clearPIN)

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.Offset = DataVariable(Offset)
    return respObj
Пример #22
0
def command_ME(cmdObj):
    """ Verify a MAC and, if successful, generate a MAC on the same data with adifferent key. """
    """ Command Pattern:
        request: Message header + 'ME' + Source TAK + Destiniation TAK + MAC + Data + End message delimiter + Message Trailer
        response: Message header + 'MF' + Error code + MAC + End Message delimiter + Message Trailer
    """
    SourceTAK = decryptKeyUnderLMK('TAK', unhexlify(cmdObj.SourceTAK.value), cmdObj.SourceTAK.scheme)
    DestinationTAK = decryptKeyUnderLMK('TAK', unhexlify(cmdObj.DestinationTAK.value), cmdObj.DestinationTAK.scheme)
    mac = calcMAC(SourceTAK, cmdObj.Data.value, "\0\0\0\0\0\0\0\0")
    finalMAC = string.upper(hexlify(mac))[:8]
    
    respObj = CommandObj()
    if cmdObj.MAC.value == finalMAC:
        respObj.ResponseCode = DataVariable('00')
        mac = calcMAC(DestinationTAK, cmdObj.Data.value, "\0\0\0\0\0\0\0\0")
        respObj.MAC = DataVariable(string.upper(hexlify(mac))[:8])
    else:    # УÑéʧ°Ü²»·µ»ØMAC
        respObj.ResponseCode = DataVariable('01')
        respObj.MAC = DataVariable('00000000')
    return respObj
Пример #23
0
def command_EA(cmdObj):
    """ Verify a PIN from interchange using the IBM 3624 method. """
    """ Command Pattern:
        request: Message header + 'EA' + ZPK + PVK + Max PIN Length + PIN Block + PIN Block Format Code + Check length + Account Number + Decimalization Table + PIN Validation data + Offset + End message delimiter + Message Trailer
        response: Message header + 'EB' + Error code + End Message delimiter + Message Trailer
    """

    respObj = CommandObj()

    ZPK = decryptKeyUnderLMK('ZPK', unhexlify(cmdObj.ZPK.value),
                             cmdObj.ZPK.scheme)
    zpk = KeyScheme(ZPK)
    pinblock = zpk.decrypt(unhexlify(cmdObj.PINBlock.value))
    (enteredPIN,
     rslt) = extrackPINFromPINBlock(pinblock, cmdObj.AccountNumber.value,
                                    cmdObj.PINBlockFormatCode.value)
    if rslt != '00':
        respObj.ResponseCode = DataVariable(rslt)
        return respObj
    print "enteredPIN=", enteredPIN
    if (len(enteredPIN) < string.atoi(cmdObj.CheckLength.value)) or (
            len(enteredPIN) > string.atoi(cmdObj.MaxPINLength.value)):
        respObj.ResponseCode = DataVariable('24')
        return respObj

    PVK = decryptKeyUnderLMK('PVK', unhexlify(cmdObj.PVK.value),
                             cmdObj.PVK.scheme)
    derivedPIN = genPINUsingIBMMetheod(PVK, cmdObj.AccountNumber.value,
                                       cmdObj.PINValidationData.value,
                                       cmdObj.DecimalizationTable.value)
    print "PIN=", derivedPIN
    finalPIN = genFinalPIN(derivedPIN, cmdObj.Offset.value)

    if (enteredPIN == finalPIN):
        respObj.ResponseCode = DataVariable('00')
    else:
        respObj.ResponseCode = DataVariable('01')
    return respObj
Пример #24
0
def command_MI(cmdObj):
    """ Translate a TAK from encryption under a ZMK to encryption under the LMK.
        Used to receive a key from another party. """
    """ Command Pattern:
        request: Message header + 'MI' + ZMK + TAK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
        response: Message header + 'MJ' + Error code + TAK + Check Value + End Message delimiter + Message Trailer
    """

    (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj)
    ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                             cmdObj.ZMK.scheme)
    takScheme = KeyScheme(ZMK, cmdObj.TAK.scheme)
    clearTAK = takScheme.decrypt(unhexlify(cmdObj.TAK.value))

    cipherTAK = encryptKeyUnderLMK('TAK', clearTAK, schemeLMK)
    tak = KeyScheme(clearTAK)
    kcv = hexlify(tak.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.TAK = KeyVariable(hexlify(cipherTAK).upper(), schemeLMK)
    respObj.CheckValue = DataVariable(kcv[:kcvLength])
    return respObj
Пример #25
0
def command_AG(cmdObj):
    """ Translate a TAK from encryption under the LMK to encryption under a TMK.
		Used to send a key to a terminal. """
    """ Command Pattern:
	    request: Message header + 'AG' + TMK + TAK + Atalla Variant + Delimiter + Key Scheme TMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
	    response: Message header + 'AH' + Error code + TAK + Check Value + End Message delimiter + Message Trailer
	"""

    (schemeTMK, schemeLMK, kcvLength) = extractTMKSchemeAndKcvLength(cmdObj)
    TMK = decryptKeyUnderLMK('TMK', unhexlify(cmdObj.TMK.value),
                             cmdObj.TMK.scheme)
    clearTAK = decryptKeyUnderLMK('TAK', unhexlify(cmdObj.TAK.value),
                                  cmdObj.TAK.scheme)
    tmkScheme = KeyScheme(TMK, schemeTMK)
    cipherTAK = tmkScheme.encrypt(clearTAK)

    tak = KeyScheme(clearTAK)
    kcv = hexlify(tak.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.TAK = KeyVariable(hexlify(cipherTAK).upper(), schemeTMK)
    respObj.CheckValue = DataVariable(kcv[:kcvLength])
    return respObj
Пример #26
0
def command_GC(cmdObj):
    """ Translate a ZPK from encryption under the LMK to encryption under a ZMK.
		Used to transmit a ZPK to another party. """
    """ Command Pattern:
	    request: Message header + 'GC' + ZMK + ZPK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer
	    response: Message header + 'GD' + Error code + ZPK + Check Value + End Message delimiter + Message Trailer
	"""

    (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj)
    ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                             cmdObj.ZMK.scheme)
    clearZPK = decryptKeyUnderLMK('ZPK', unhexlify(cmdObj.ZPK.value),
                                  cmdObj.ZPK.scheme)
    zmkScheme = KeyScheme(ZMK, schemeZMK)
    cipherZPK = zmkScheme.encrypt(clearZPK)

    zpk = KeyScheme(clearZPK)
    kcv = hexlify(zpk.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.ZPK = KeyVariable(hexlify(cipherZPK).upper(), schemeZMK)
    respObj.CheckValue = DataVariable(kcv[:kcvLength])
    return respObj
Пример #27
0
def command_A6(cmdObj):
    """ To import a key encrypted under a ZMK. """
    """ Command Pattern:
	    request: Message header + 'A6' + Key Type + ZMK + Key + Key Scheme LMK + Atalla Variant + End message delimiter + Message Trailer
	    response: Message header + 'A7' + Error code + Key + Check Value + End Message delimiter + Message Trailer
	"""

    ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value),
                             cmdObj.ZMK.scheme)
    keyScheme = KeyScheme(ZMK, cmdObj.Key.scheme)
    clearKey = keyScheme.decrypt(unhexlify(cmdObj.Key.value))

    keyType = Configure.KeyTypeTable[cmdObj.KeyType.value]
    cipherKey = encryptKeyUnderLMK(keyType, clearKey,
                                   cmdObj.KeySchemeLMK.value)
    key = KeyScheme(clearKey)
    kcv = hexlify(key.encrypt("\0\0\0\0\0\0\0\0")).upper()

    respObj = CommandObj()
    respObj.ResponseCode = DataVariable('00')
    respObj.Key = KeyVariable(
        hexlify(cipherKey).upper(), cmdObj.KeySchemeLMK.value)
    respObj.CheckValue = DataVariable(kcv[:6])
    return respObj
Пример #28
0
def GenCardInfo(mp, cardno, expiry, offset):
    keyConfig = GetKeyConfig(cardno)
    AccountNumber = cardno[-13:-1]
    # generate pin
    command = mp.command_hash['EE']
    obj = Command.CommandObj()
    obj.MessageHeader = '    '
    obj.Code = DataVariable('EE')
    obj.PVK = KeyVariable(keyConfig.PVK)
    obj.Offset = DataVariable(offset[:6] + 'FFFFFF')
    obj.CheckLength = DataVariable('06')
    obj.AccountNumber = DataVariable(AccountNumber)
    obj.DecimalizationTable = DataVariable('1234567890123456')
    obj.PINValidationData = DataVariable(AccountNumber[:-1] + 'N')
    message = command.pack(obj)
    #	print message
    resp = mp.ProcessMessage(message)
    #	print resp
    command = mp.command_hash['EF']
    pinResp = command.unpack(resp)
    #	print pinResp.PIN
    command = mp.command_hash['NG']
    obj = Command.CommandObj()
    obj.MessageHeader = '    '
    obj.Code = DataVariable('NG')
    obj.PIN = pinResp.PIN
    obj.AccountNumber = DataVariable(AccountNumber)
    message = command.pack(obj)
    #	print message
    resp = mp.ProcessMessage(message)
    command = mp.command_hash['NH']
    #	print resp
    pinResp = command.unpack(resp)

    # generate cvv
    command = mp.command_hash['CW']
    obj = Command.CommandObj()
    obj.MessageHeader = '    '
    obj.Code = DataVariable('CW')
    obj.CVK_AB = KeyVariable(keyConfig.CVK_A + keyConfig.CVK_B)
    obj.PrimaryAccountNumber = DataVariable(cardno + ';')
    obj.ExpirationDate = DataVariable(expiry)
    obj.ServiceCode = DataVariable('106')
    message = command.pack(obj)
    #	print message
    resp = mp.ProcessMessage(message)
    #	print resp
    command = mp.command_hash['CX']
    cvvResp = command.unpack(resp)
    #	print cvvResp.CVV

    return (pinResp.PIN, cvvResp.CVV)