Skip to main content

A Python package for EMV cryptography in payment systems

Project description

PyEMV

PyPI Test coverage

This package provides methods for the generation of the Application Cryptograms (TC, ARQC, or AAC) generated by the ICC and the Authorisation Response Cryptogram (ARPC) generated by the issuer and verified by the ICC. In addition, this package supports secure messaging integrity and confidentiality.

Install:

pip install pyemv

PyEMV consists of the following modules:

  • kd - Key Derivation support for ICC master keys and session keys

  • ac - Application Cryptogram support for ARQC, AAC, TC, and ARPC

  • sm - Secure Messaging support for script command integrity and confidentiality. It also provides support for PIN blocks.

  • cvn - Putting it all together for various Cryptogram Version Numbers

Key Derivation

ICC Master Key derivation method A and B:

>>> from pyemv import kd
>>> iss_mk = bytes.fromhex('0123456789ABCDEFFEDCBA9876543210')
>>> pan = b'99012345678901234'
>>> psn = b'45'
>>> icc_mk_a = kd.derive_icc_mk_a(iss_mk, pan, psn)
>>> icc_mk_a.hex().upper()
'67F8292358083E5EA7AB7FDA58D53B6B'
>>> icc_mk_b = kd.derive_icc_mk_b(iss_mk, pan, psn)
>>> icc_mk_b.hex().upper()
'985EC4FD3EDF6162E31AF1C7D0543416'

Common Session Key derivation:

>>> r = bytes.fromhex('1234567890123456')
>>> sk = kd.derive_common_sk(icc_mk_a, r)
>>> sk.hex().upper()
'29B33180E567CE38EA4CBC9D753B0E61'

Cryptogram Generation

Application Request Cryptogram generation:

>>> from pyemv import ac
>>> ac_data = bytes.fromhex('0123456789ABCDEF0123456789ABCDEF')
>>> arqc = ac.generate_ac(sk, ac_data)
>>> arqc.hex().upper()
'FA624250B008B59A'

Application Response Cryptogram generation method 1 and 2:

>>> arpc_rc = bytes.fromhex('0000')
>>> arpc = ac.generate_arpc_1(sk, arqc, arpc_rc)
>>> arpc.hex().upper()
'45D4255EEF10C920'
>>> csu = bytes.fromhex('00000000')
>>> arpc = ac.generate_arpc_2(sk, arqc, csu)
>>> arpc.hex().upper()
'CB56FA40'

Secure Messaging

Secure Messaging Integrity (MAC):

>>> from pyemv import sm
>>> sk_smi = bytes.fromhex('0123456789ABCDEFFEDCBA9876543210')
>>> command = bytes.fromhex('8424000008')
>>> mac = sm.generate_command_mac(sk_smi, command)
>>> mac.hex().upper()
'0BFFF5DF3FAA24E1'

Secure Messaging Confidentiality:

>>> pin_block = sm.format_iso9564_2_pin_block(b'9999')
>>> pin_block.hex().upper()
'249999FFFFFFFFFF'
>>> sk_smc = bytes.fromhex('0123456789ABCDEFFEDCBA9876543210')
>>> enc_data = sm.encrypt_command_data(sk_smc, pin_block,
...                                    sm.EncryptionType.EMV)
>>> enc_data.hex().upper()
'5A862D1381CCB94822CFDD706A376178'

Cryptogram Version Number

Cryptogram Version Number (CVN) module demonstrates how application cryptogram generation, key derivation and secure messaging come together.

>>> from pyemv import cvn
>>> cvn18 = cvn.VisaCVN18(
...     iss_mk_ac=bytes.fromhex('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'),
...     iss_mk_smi=bytes.fromhex('BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'),
...     iss_mk_smc=bytes.fromhex('CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'),
...     pan=b'1234567890123456',
...     psn=b'00')
>>> atc = bytes.fromhex('0FFF')
>>> arqc = cvn18.generate_ac(
...     tag_9f02=bytes.fromhex('000000009999'),
...     tag_9f03=bytes.fromhex('000000000000'),
...     tag_9f1a=bytes.fromhex('0840'),
...     tag_95=bytes.fromhex('8000048000'),
...     tag_5f2a=bytes.fromhex('0840'),
...     tag_9a=bytes.fromhex('991231'),
...     tag_9c=bytes.fromhex('01'),
...     tag_9f37=bytes.fromhex('52BF4585'),
...     tag_82=bytes.fromhex('1800'),
...     tag_9f36=atc,
...     tag_9f10=bytes.fromhex('06011203A0B800'))
>>> arqc.hex().upper()
'769577B5ABE9FE62'
>>> arpc = cvn18.generate_arpc(
...     tag_9f26=arqc,
...     tag_9f36=atc,
...     csu=bytes.fromhex('00000000'))
>>> arpc.hex().upper()
'76503F48'
>>> command_mac = cvn18.generate_command_mac(
...         command_header=bytes.fromhex('8418000008'),
...         tag_9f26=arqc,
...         tag_9f36=atc)
>>> command_mac.hex().upper()
'B5CB29759F9C3919'
>>> pin_command = cvn18.generate_pin_change_command(
...         pin=b'9999',
...         tag_9f26=arqc,
...         tag_9f36=atc)
>>> pin_command.hex().upper()
'84240002182DC7A061323BA62472BC5308BD291B5F665B3A927E60661E'

Contribute

PyEMV is hosted on GitHub.

Feel free to fork and send contributions over.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyemv-1.2.0.tar.gz (25.5 kB view hashes)

Uploaded Source

Built Distribution

pyemv-1.2.0-py3-none-any.whl (20.6 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page