Metadata-Version: 2.1
Name: pyemv
Version: 1.2.0
Summary: A Python package for EMV cryptography in payment systems
Home-page: https://github.com/knovichikhin/pyemv
Author: Konstantin Novichikhin
Author-email: konstantin.novichikhin@gmail.com
License: MIT
Keywords: emv arqc arpc
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.5
Description-Content-Type: text/x-rst
Requires-Dist: cryptography (>=2.8)

PyEMV
-----

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

.. code-block:: python

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

.. code-block:: python

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

Cryptogram Generation
~~~~~~~~~~~~~~~~~~~~~

Application Request Cryptogram generation:

.. code-block:: python

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

.. code-block:: python

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

.. code-block:: python

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

.. code-block:: python

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

.. code-block:: python

    >>> 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 <https://github.com/knovichikhin/pyemv>`_.

Feel free to fork and send contributions over.

.. |pypi| image:: https://img.shields.io/pypi/v/pyemv.svg
    :alt: PyPI
    :target:  https://pypi.org/project/pyemv/

.. |coverage| image:: https://codecov.io/gh/knovichikhin/pyemv/branch/master/graph/badge.svg
    :alt: Test coverage
    :target: https://codecov.io/gh/knovichikhin/pyemv


