=====================================
Cryptnox Python Communication Library
=====================================
.. image:: https://img.shields.io/pypi/v/cryptnoxpy
:target: https://pypi.org/project/cryptnoxpy
.. image:: https://readthedocs.org/projects/cryptnoxpy/badge/?version=latest
:target: https://cryptnoxpy.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
**Warning: This is a beta release of the software.
It is released for development purposes.
Use at your own risk.**
A Python3 library to use the `Cryptnox smartcard applet <https://www.cryptnox.com/>`_.
It provides high level functions to send instructions to a Cryptnox Hardware Wallet Card and to manage its lifecycle.
The core module is *CryptnoxPy* which provides a *Connection* class to
establish a channel of communication that can be used to initialize a card instance through the
factory method.
To buy NFC enabled cards that are supported by this library go to:
`https://www.cryptnox.com/ <https://www.cryptnox.com/>`_
License
-------
The library is available under dual licensing. You can use the library under the
conditions of `GNU LESSER GENERAL PUBLIC LICENSE 3.0+ <https://www.gnu.org/licenses/lgpl-3.0.en.html>`_
or `contact us <info@cryptnox.ch>`_ to ask about commercial licensing.
Documentation
-------------
API documentation can be found in HTML format in the `docs folder <docs/html/index.html>`_
It is generated using Sphynx from the code and can be generated in other formats too.
Installation and requirements
-----------------------------
Requires :
* Python 3.6-3.12
* PCSCd on Linux
Ubuntu / Debian
.. code-block:: bash
sudo apt-get install swig python3-pip python3-setuptools pcscd libpcsclite-dev
pip install -U setuptools
Fedora / CentOS / RHEL
.. code-block:: bash
yum install swig python3-pip python3-setuptools pcsc-lite-ccid
pip install -U setuptools
On some Linux, starts PCSCd service
.. code-block:: bash
(sudo) systemctl start pcscd
(sudo) systemctl enable pcscd
Mac OSX
.. code-block:: bash
brew install swig
Installation of this library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Make sure that you installed the required packages for your system.
See the "Requires" section above.
Install with pip:
.. code-block:: bash
pip install cryptnoxpy
Install from source:
Download and run in its directory:
.. code-block:: bash
pip install .
or:
.. code-block:: bash
pip install git+ssh://git@github.com/Cryptnox-Software/cryptnoxpy.git
This might require *sudo* on some systems.
Remove:
.. code-block:: bash
pip uninstall cryptnoxpy
Installation issues
^^^^^^^^^^^^^^^^^^^
If the **Linux system doesn\'t have Python 3.6, 3.7, 3.8 nor 3.9**\ , install
Python 3.7 with the following recipe (Debian like):
.. code-block:: bash
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev swig libpcsclite-dev
sudo apt-get install -y libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm git
sudo apt-get install -y libncurses5-dev libncursesw5-dev xz-utils tk-dev pcscd opensc
wget https://www.python.org/ftp/python/3.7.8/Python-3.7.8.tgz
tar xf Python-3.7.8.tgz
cd Python-3.7.8
./configure --enable-optimizations
make -j8 build_all
sudo make -j8 altinstall
sudo pip3.7 install git+ssh://git@gitlab.com/cryptnox-phase2/cryptnoxpy.git
# or (if issue about agent forwarding with sudo) :
cd ~
git clone git@gitlab.com:cryptnox-phase2/cryptnoxpy.git
cd cryptnoxpy
sudo pip3.7 install .
In case of **pyscard can\'t be installed** automatically with pip:
1. Try to pip3 install with sudo or root: ``sudo pip install .``
2. If still a failure, install the following packages: Needed if pyscard can\'t be installed from package manager ``sudo apt install python3-dev swig libpcsclite-dev`` then retry ``sudo pip install .``.
If you use **contactless readers** on Linux, the RFID modules need to be disabled :
.. code-block:: bash
sudo rmmod pn533_usb
sudo rmmod pn533
sudo rm -r /lib/modules/*/kernel/drivers/nfc/pn533
Update issues
^^^^^^^^^^^^^
In case you just want to update the package, with old pip version on some Linux, it is better to remove and reinstall the package:
.. code-block:: bash
sudo pip uninstall cryptnoxpy
sudo pip install .
Library use
------------------------------------
To get the card a connection has to be established with the reader's index. The connection can
then be passed to the factory that will initialize an object for the card in the reader from the
correct class for the card type and version.
.. code-block:: python
import cryptnoxpy
try:
connection = cryptnoxpy.Connection(0)
except cryptnoxpy.ReaderException:
print("Reader not found on index")
else:
try:
card = cryptnoxpy.factory.get_card(connection)
except cryptnoxpy.CryptnoxException as error:
# There is an issue with loading the card
# CryptnoxException is the base exception class for module
print(error)
else:
# Card is loaded and can be used
print(f"Card serial number: {card.serial_number}")
The factory will:
* connect to the card
* select the applet
* read the applet parameters
* select class to handle the card
The card contains basic information:
* card.serial_number : Integer : Card/applet instance Unique ID
* card.applet_version : 3 integers list : Applet version (ex. 1.2.2)
Remote connection
^^^^^^^^^^^^^^^^^
The connection can also be initialized with a socket connection client in a list, and a True value for the 'remote' parameter.
This enables use with a remote client, communicating apdu commands over the socket connection.
.. code-block:: python
import cryptnoxpy
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((SERVER_IP,SERVER_PORT))
server.listen()
conn, addr = server.accept()
try:
connection = cryptnoxpy.Connection(0,False,[conn],True)
except cryptnoxpy.ReaderException:
print("Reader not found on index")
else:
try:
card = cryptnoxpy.factory.get_card(connection)
except cryptnoxpy.CryptnoxException as error:
# There is an issue with loading the card
# CryptnoxException is the base exception class for module
print(error)
else:
# Card is loaded and can be used
print(f"Card serial number: {card.serial_number}")
Initialization and pairing
^^^^^^^^^^^^^^^^^^^^^^^^^^
Right after the installation, the applet is not initialized, and the user needs
to send some parameters to use the card. The initialization can be executed once.
Any change of the base parameters requires a full applet reinstallation
(except PIN/PUK change).
After the initialization, the card and the PC must share a common secret to be
used as authenticated secure channel. This secret is required any time further,
to communicate with the card (using a secure channel). The registration of this
common secret is done during the init phase.
The init parameters required are :
* Name (up to 20 chars string)
* Email (up to 60 chars string)
* PIN (9 digits string)
* PUK (15 digits string)
* optional : the first Paring Secret (32 bytes bytearray)
.. code-block:: python
pairing_key = card.init(name, email, pin, puk, pairing_secret)
The returned data is the first PairingKey (32 bytes byte-array) and its index (0) :
``0x00 + ParingKeySlot0``
During the initialization phase, until the user public key for authentication
registration is allowed, the set_pairing_key command is also allowed.
Then set_pairing_key needs the applet to have the signature unlocked.
After getting the pairing_key, the user needs to store it in a safe place.
In the case the client would communicate with several cards, the user needs to
associate the pairing_key with the instance serial number of the card, so that the user
client can keep track of multiple cards, and use the right one with the right
card. The pairing_key must be saved in a file to reconnect the next time to this
card. It should be saved with the serial number of card in order to associate this card with this
key.
A common hardcoded PairingKey can be used.
After this init phase, the secure channel must be used with all communications
with the card. A secure channel is an encrypted and 2-ways authenticated link
layer with the card using standards APDU messages. Many applet commands require
a secure channel.
PIN
^^^
The PIN chosen during the initialization needs to be provided after each card
reset, and a secure channel is opened.
To test a PIN string, simply use:
.. code-block:: python
card.verify_pin(pin)
Seed administration
^^^^^^^^^^^^^^^^^^^
The applet manages a 256 bits master secret called the "seed". This is the BIP32
Master Seed, and can be externally computed from a mnemonic to a binary seed
using BIP39. The key pairs used for ECDSA are then computationally derived from
this seed using BIP32 derivation scheme.
Seed generation
~~~~~~~~~~~~~~~
The seed can be generated in the card using the random number generator in the
java chip system (AIS 20 class DRG.3). Doing this way, the seed secret never
escapes the card protection.
The method to generate a new seed key is:
.. code-block:: python
card.generate_seed(pin)
The card can also randomly generate BIP39 mnemonics words list. But in this
case, the query answer is only output and not used internally by the card.
It is administrator responsibility to get a mnemonic using the GENERATE MNEMONIC
command and then eventually compute the corresponding seed, which can be
uploaded in the card using RECOVER KEY command.
We don't recommend doing so, this is very insecure, as the seed is exposed in
clear and full in the user's system.
Recovery
~~~~~~~~
The Cryptnox applet can load binary seed.
The seed is loaded in the card using this method:
.. code-block:: python
card.load_seed(seed, pin)
Seed is 32 bytes.
Once this seed is loaded in the card using the load_seed method, this card now
behaves like were (or the one) it was backup. Be aware that key derivation
paths are not backup, and must be identical to retrieve the same key pairs.
See derivation and key system just below for more details.
For more details about the recovery, see load_seed operation in the API documentation.
Derivation and keys system
^^^^^^^^^^^^^^^^^^^^^^^^^^
The card applet is fully compliant with
`BIP32 <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>`_,
except the maximum depth of derivation from the master key is 8 levels.
It can be turned on for the card to return extended public keys for use in applications
requiring it.
The card stores the present key pair (and its parent), used for signature.
This can be changed using the derive method, and also during a signature
command, giving a relative path (from the present key pair), or in an absolute path
(from the master key pair). See derive method in the API documentation.
Any derivation aborts any opened signing sessions and resets the authentications
for signature. The generated key is used for all subsequent sign sessions.
The ability to start derivation from the parent keys allows to more efficiently
switch between children of the same key. Note however that only the immediate
parent of the current key is cached so one cannot use this to go back in the
keys hierarchy.
For ease of use, the user can derive from the root master node key pair
(absolute path) at each card startup, or even before each signature.
This takes a couple of seconds. So this is better to store intermediate public
keys hash and check the status to observe the current key pair in use.
This off-card complex key management is not needed if the signatures volume
is below one thousand per day.
See derive and sign methods in the API documentation.
EC Signature
^^^^^^^^^^^^
The derivation of the key pair node can be also possible using the signature
command (relative or absolute).
The card applet can sign any 256 bits hash provided, using ECDSA with 256k1 EC
parameters. Most of the blockchain system used SHA2-256 to hash the message,
but this card applet is agnostic from this point, since the signature is performed on
a hash provided by the user. Note that this hash needs to be confirmed by the
users beforehand, when they provide their EC384 signature of this hash.
The code to sign with the EC current key node is:
.. code-block:: python
signature = card.sign(data_hash, cryptnoxpy.Derivation.CURRENT_KEY)
data_hash is a byte-array containing the EC hash to sign using ECDSA ecp256k1:
The signature a byte array, encoded as an ASN1 DER sequence of two INTEGER values, r and s.
See the sign method in the API documentation for more information.
=========
Changelog
=========
All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_\ ,
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
`Unreleased <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.3.0...HEAD>`_
-------------------------------------------------------------------------------------
`2.4.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.3.0...2.4.0>`_ - 2023-01-31
-----------------------------------------------------------------------------------------------
Changed
^^^^^^^
- Remote connection message format, not compatible with previous version
`2.3.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.2.1...2.3.0>`_ - 2022-11-28
-----------------------------------------------------------------------------------------------
Added
^^^^^
- Ability to write and read custom bytes from select command
`2.2.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.2.0...2.2.1>`_ - 2022-07-14
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
- Installation for Python 3.10
`2.2.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.1.1...2.2.0>`_ - 2022-07-13
-----------------------------------------------------------------------------------------------
Added
^^^^^
- Support for Python 3.10
Removed
^^^^^^^
- Support for Python 3.6
Fixed
^^^^^
- `get_public_key` raises an unhandled exception when asking for current key with a derivation path
`2.1.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.1.0...2.1.1>`_ - 2022-06-13
-----------------------------------------------------------------------------------------------
Added
^^^^^
- Add optional "hexed" parameter in get_public_key of cards
`2.1.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.3...v2.1.0>`_ - 2022-06-01
-----------------------------------------------------------------------------------------------
Added
^^^^^
- Add option for cards from remote connection
`2.0.3 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.2...v2.0.3>`_ - 2022-03-14
-----------------------------------------------------------------------------------------------
Changed
^^^^^^^
- Installation instructions added missing instructions
Fixed
^^^^^
- `generate_seed` command allowed without previously verifying PIN code
`2.0.2 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.1...v2.0.2>`_ - 2022-03-14
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
- `unblock_pin` command shows "PIN code wasn't authorized" when card is not locked
`2.0.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.0...v2.0.1>`_ - 2022-01-03
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
- Printing debug data during requests call for certificates
`2.0.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.6...v2.0.0>`_ - 2022-01-03
-----------------------------------------------------------------------------------------------
Added
^^^^^
- New cad type, NFT, with limited functionality intended for keeping one NFT
- Method for checking private key validity
Changed
^^^^^^^
- User data read and write property to list
- pyscard on windows fixed to version 2.0.1, in pipenv all OSes.
`1.1.6 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.5...v1.1.6>`_ - 2021-11-03
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
* Debug parameter not passed when creating card class
`1.1.5 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.4...v1.1.5>`_ - 2021-10-29
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
* Genuineness check made more resilient to exceptions
`1.1.4 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.3...v1.1.4>`_ - 2021-10-21
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
* Opening secure channel with G0 card throws exception
`1.1.3 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.2...v1.1.3>`_ - 2021-10-20
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
* sign operation throws error if PIN code is not provided when user key is used for authentication.
`1.1.2 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.1...v1.1.2>`_ - 2021-10-07
-----------------------------------------------------------------------------------------------
Fixed
^^^^^
* Handling of error response from the card for not authenticated
`1.1.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.0...v1.1.1>`_ - 2021-10-06
-----------------------------------------------------------------------------------------------
Changed
^^^^^^^
* User data size increased to 3600 bytes
Fixed
^^^^^
* Set PIN-less path didn't convert input path to correct values for card
* Setting PIN-less path and PIN authentication doesn't set flags for indication
* Sign method doesn't fill up given PIN code with 0s up to 9 characters
`1.1.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.0.4...v1.1.0>`_ - 2021-09-24
-----------------------------------------------------------------------------------------------
Added
^^^^^
* Origin property for indicating if the card is original or not or check can't be done.
Changed
^^^^^^^
* PyScard updated to 2.0.2
Fixed
^^^^^
* When card is not initialized seed_source property throws exception. Return `SeedSource.NO_SEED` instead
* When seed is generated in the card the flag for it stays the same
* Operation unlock_pin doesn't raise exception when card is not locked
`1.0.4 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.0.3...v1.0.4>`_ - 2021-09-09
-----------------------------------------------------------------------------------------------
Changed
^^^^^^^
* Improvements in setup
`1.0.3 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.0.0...v1.0.3>`_ - 2021-09-07
-----------------------------------------------------------------------------------------------
Changed
^^^^^^^
* Documentation changed to rst
* Version number stored in the module instead of getting it from pbr
Removed
^^^^^^^
* PBR dependency
Fixed
^^^^^
* PyPI doesn't install dependencies
`1.0.0 <https://github.com/Cryptnox-Software/cryptnoxpy/releases/tag/v1.0.0>`_ - 2021-08-20
-------------------------------------------------------------------------------------------
Added
^^^^^
* Card operations
* Pipfile and requirements for setting up environment
* Setup file to install the library
Raw data
{
"_id": null,
"home_page": "https://www.cryptnox.com/",
"name": "cryptnoxpy",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.13,>=3.7",
"maintainer_email": null,
"keywords": "python, cryptography",
"author": "Cryptnox SA",
"author_email": "info@cryptnox.ch",
"download_url": "https://files.pythonhosted.org/packages/7c/37/2c6fef203e9609420be8e8fff85a922accbcab30f2e17f1a34ed722353b2/cryptnoxpy-2.5.3.tar.gz",
"platform": "any",
"description": "=====================================\r\nCryptnox Python Communication Library\r\n=====================================\r\n\r\n.. image:: https://img.shields.io/pypi/v/cryptnoxpy\r\n :target: https://pypi.org/project/cryptnoxpy\r\n\r\n.. image:: https://readthedocs.org/projects/cryptnoxpy/badge/?version=latest\r\n :target: https://cryptnoxpy.readthedocs.io/en/latest/?badge=latest\r\n :alt: Documentation Status\r\n\r\n**Warning: This is a beta release of the software.\r\nIt is released for development purposes. \r\nUse at your own risk.**\r\n\r\nA Python3 library to use the `Cryptnox smartcard applet <https://www.cryptnox.com/>`_.\r\nIt provides high level functions to send instructions to a Cryptnox Hardware Wallet Card and to manage its lifecycle. \r\nThe core module is *CryptnoxPy* which provides a *Connection* class to \r\nestablish a channel of communication that can be used to initialize a card instance through the \r\nfactory method.\r\n\r\nTo buy NFC enabled cards that are supported by this library go to: \r\n`https://www.cryptnox.com/ <https://www.cryptnox.com/>`_\r\n\r\nLicense\r\n-------\r\n\r\nThe library is available under dual licensing. You can use the library under the \r\nconditions of `GNU LESSER GENERAL PUBLIC LICENSE 3.0+ <https://www.gnu.org/licenses/lgpl-3.0.en.html>`_ \r\nor `contact us <info@cryptnox.ch>`_ to ask about commercial licensing. \r\n\r\nDocumentation\r\n-------------\r\n\r\nAPI documentation can be found in HTML format in the `docs folder <docs/html/index.html>`_ \r\nIt is generated using Sphynx from the code and can be generated in other formats too.\r\n\r\nInstallation and requirements\r\n-----------------------------\r\n\r\nRequires :\r\n\r\n\r\n* Python 3.6-3.12\r\n* PCSCd on Linux\r\n\r\nUbuntu / Debian\r\n\r\n.. code-block:: bash\r\n\r\n sudo apt-get install swig python3-pip python3-setuptools pcscd libpcsclite-dev\r\n pip install -U setuptools\r\n\r\nFedora / CentOS / RHEL\r\n\r\n.. code-block:: bash\r\n\r\n yum install swig python3-pip python3-setuptools pcsc-lite-ccid\r\n pip install -U setuptools\r\n\r\nOn some Linux, starts PCSCd service\r\n\r\n.. code-block:: bash\r\n\r\n (sudo) systemctl start pcscd\r\n (sudo) systemctl enable pcscd\r\n\r\nMac OSX\r\n\r\n.. code-block:: bash\r\n\r\n brew install swig\r\n\r\nInstallation of this library\r\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n\r\nMake sure that you installed the required packages for your system.\r\nSee the \"Requires\" section above.\r\n\r\nInstall with pip:\r\n\r\n.. code-block:: bash\r\n\r\n pip install cryptnoxpy\r\n\r\nInstall from source:\r\n\r\nDownload and run in its directory:\r\n\r\n.. code-block:: bash\r\n\r\n pip install .\r\n\r\nor:\r\n\r\n.. code-block:: bash\r\n\r\n pip install git+ssh://git@github.com/Cryptnox-Software/cryptnoxpy.git\r\n\r\nThis might require *sudo* on some systems.\r\n\r\nRemove:\r\n\r\n.. code-block:: bash\r\n\r\n pip uninstall cryptnoxpy\r\n\r\nInstallation issues\r\n^^^^^^^^^^^^^^^^^^^\r\n\r\nIf the **Linux system doesn\\'t have Python 3.6, 3.7, 3.8 nor 3.9**\\ , install\r\nPython 3.7 with the following recipe (Debian like):\r\n\r\n.. code-block:: bash\r\n\r\n sudo apt-get install -y make build-essential libssl-dev zlib1g-dev swig libpcsclite-dev\r\n sudo apt-get install -y libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm git\r\n sudo apt-get install -y libncurses5-dev libncursesw5-dev xz-utils tk-dev pcscd opensc\r\n wget https://www.python.org/ftp/python/3.7.8/Python-3.7.8.tgz\r\n tar xf Python-3.7.8.tgz\r\n cd Python-3.7.8\r\n ./configure --enable-optimizations\r\n make -j8 build_all\r\n sudo make -j8 altinstall\r\n\r\n sudo pip3.7 install git+ssh://git@gitlab.com/cryptnox-phase2/cryptnoxpy.git\r\n\r\n # or (if issue about agent forwarding with sudo) :\r\n\r\n cd ~\r\n git clone git@gitlab.com:cryptnox-phase2/cryptnoxpy.git\r\n cd cryptnoxpy\r\n sudo pip3.7 install .\r\n\r\nIn case of **pyscard can\\'t be installed** automatically with pip:\r\n\r\n 1. Try to pip3 install with sudo or root: ``sudo pip install .``\r\n 2. If still a failure, install the following packages: Needed if pyscard can\\'t be installed from package manager ``sudo apt install python3-dev swig libpcsclite-dev`` then retry ``sudo pip install .``.\r\n\r\nIf you use **contactless readers** on Linux, the RFID modules need to be disabled :\r\n\r\n.. code-block:: bash\r\n\r\n sudo rmmod pn533_usb\r\n sudo rmmod pn533\r\n sudo rm -r /lib/modules/*/kernel/drivers/nfc/pn533\r\n\r\nUpdate issues\r\n^^^^^^^^^^^^^\r\n\r\nIn case you just want to update the package, with old pip version on some Linux, it is better to remove and reinstall the package:\r\n\r\n.. code-block:: bash\r\n\r\n sudo pip uninstall cryptnoxpy\r\n sudo pip install .\r\n\r\nLibrary use\r\n------------------------------------\r\n\r\nTo get the card a connection has to be established with the reader's index. The connection can\r\nthen be passed to the factory that will initialize an object for the card in the reader from the\r\ncorrect class for the card type and version.\r\n\r\n.. code-block:: python\r\n\r\n import cryptnoxpy\r\n\r\n try:\r\n connection = cryptnoxpy.Connection(0)\r\n except cryptnoxpy.ReaderException:\r\n print(\"Reader not found on index\")\r\n else:\r\n try:\r\n card = cryptnoxpy.factory.get_card(connection)\r\n except cryptnoxpy.CryptnoxException as error:\r\n # There is an issue with loading the card\r\n # CryptnoxException is the base exception class for module\r\n print(error)\r\n else:\r\n # Card is loaded and can be used\r\n print(f\"Card serial number: {card.serial_number}\")\r\n\r\nThe factory will:\r\n\r\n* connect to the card\r\n* select the applet\r\n* read the applet parameters\r\n* select class to handle the card\r\n\r\nThe card contains basic information:\r\n\r\n* card.serial_number : Integer : Card/applet instance Unique ID\r\n* card.applet_version : 3 integers list : Applet version (ex. 1.2.2)\r\n\r\nRemote connection\r\n^^^^^^^^^^^^^^^^^\r\nThe connection can also be initialized with a socket connection client in a list, and a True value for the 'remote' parameter.\r\nThis enables use with a remote client, communicating apdu commands over the socket connection.\r\n\r\n.. code-block:: python\r\n\r\n import cryptnoxpy\r\n import socket\r\n\r\n server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)\r\n server.bind((SERVER_IP,SERVER_PORT))\r\n server.listen()\r\n conn, addr = server.accept()\r\n try:\r\n connection = cryptnoxpy.Connection(0,False,[conn],True)\r\n except cryptnoxpy.ReaderException:\r\n print(\"Reader not found on index\")\r\n else:\r\n try:\r\n card = cryptnoxpy.factory.get_card(connection)\r\n except cryptnoxpy.CryptnoxException as error:\r\n # There is an issue with loading the card\r\n # CryptnoxException is the base exception class for module\r\n print(error)\r\n else:\r\n # Card is loaded and can be used\r\n print(f\"Card serial number: {card.serial_number}\")\r\n\r\nInitialization and pairing\r\n^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n\r\nRight after the installation, the applet is not initialized, and the user needs\r\nto send some parameters to use the card. The initialization can be executed once.\r\nAny change of the base parameters requires a full applet reinstallation\r\n(except PIN/PUK change).\r\n\r\nAfter the initialization, the card and the PC must share a common secret to be\r\nused as authenticated secure channel. This secret is required any time further,\r\nto communicate with the card (using a secure channel). The registration of this\r\ncommon secret is done during the init phase.\r\n\r\nThe init parameters required are :\r\n\r\n\r\n* Name (up to 20 chars string)\r\n* Email (up to 60 chars string)\r\n* PIN (9 digits string)\r\n* PUK (15 digits string)\r\n* optional : the first Paring Secret (32 bytes bytearray)\r\n\r\n.. code-block:: python\r\n\r\n pairing_key = card.init(name, email, pin, puk, pairing_secret)\r\n\r\nThe returned data is the first PairingKey (32 bytes byte-array) and its index (0) :\r\n``0x00 + ParingKeySlot0``\r\n\r\nDuring the initialization phase, until the user public key for authentication\r\nregistration is allowed, the set_pairing_key command is also allowed.\r\nThen set_pairing_key needs the applet to have the signature unlocked.\r\n\r\nAfter getting the pairing_key, the user needs to store it in a safe place.\r\nIn the case the client would communicate with several cards, the user needs to\r\nassociate the pairing_key with the instance serial number of the card, so that the user\r\nclient can keep track of multiple cards, and use the right one with the right\r\ncard. The pairing_key must be saved in a file to reconnect the next time to this\r\ncard. It should be saved with the serial number of card in order to associate this card with this\r\nkey.\r\n\r\nA common hardcoded PairingKey can be used.\r\n\r\nAfter this init phase, the secure channel must be used with all communications\r\nwith the card. A secure channel is an encrypted and 2-ways authenticated link\r\nlayer with the card using standards APDU messages. Many applet commands require\r\na secure channel.\r\n\r\nPIN\r\n^^^\r\n\r\nThe PIN chosen during the initialization needs to be provided after each card\r\nreset, and a secure channel is opened.\r\n\r\nTo test a PIN string, simply use:\r\n\r\n.. code-block:: python\r\n\r\n card.verify_pin(pin)\r\n\r\nSeed administration\r\n^^^^^^^^^^^^^^^^^^^\r\n\r\nThe applet manages a 256 bits master secret called the \"seed\". This is the BIP32\r\nMaster Seed, and can be externally computed from a mnemonic to a binary seed\r\nusing BIP39. The key pairs used for ECDSA are then computationally derived from\r\nthis seed using BIP32 derivation scheme.\r\n\r\nSeed generation\r\n~~~~~~~~~~~~~~~\r\n\r\nThe seed can be generated in the card using the random number generator in the\r\njava chip system (AIS 20 class DRG.3). Doing this way, the seed secret never\r\nescapes the card protection.\r\n\r\nThe method to generate a new seed key is:\r\n\r\n.. code-block:: python\r\n\r\n card.generate_seed(pin)\r\n\r\nThe card can also randomly generate BIP39 mnemonics words list. But in this\r\ncase, the query answer is only output and not used internally by the card.\r\nIt is administrator responsibility to get a mnemonic using the GENERATE MNEMONIC\r\ncommand and then eventually compute the corresponding seed, which can be\r\nuploaded in the card using RECOVER KEY command.\r\nWe don't recommend doing so, this is very insecure, as the seed is exposed in\r\nclear and full in the user's system.\r\n\r\nRecovery\r\n~~~~~~~~\r\n\r\nThe Cryptnox applet can load binary seed.\r\n\r\nThe seed is loaded in the card using this method:\r\n\r\n.. code-block:: python\r\n\r\n card.load_seed(seed, pin)\r\n\r\nSeed is 32 bytes.\r\n\r\nOnce this seed is loaded in the card using the load_seed method, this card now\r\nbehaves like were (or the one) it was backup. Be aware that key derivation\r\npaths are not backup, and must be identical to retrieve the same key pairs.\r\nSee derivation and key system just below for more details.\r\n\r\nFor more details about the recovery, see load_seed operation in the API documentation.\r\n\r\nDerivation and keys system\r\n^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n\r\nThe card applet is fully compliant with\r\n`BIP32 <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>`_,\r\nexcept the maximum depth of derivation from the master key is 8 levels.\r\nIt can be turned on for the card to return extended public keys for use in applications\r\nrequiring it.\r\n\r\nThe card stores the present key pair (and its parent), used for signature.\r\nThis can be changed using the derive method, and also during a signature\r\ncommand, giving a relative path (from the present key pair), or in an absolute path\r\n(from the master key pair). See derive method in the API documentation.\r\n\r\nAny derivation aborts any opened signing sessions and resets the authentications\r\nfor signature. The generated key is used for all subsequent sign sessions.\r\n\r\nThe ability to start derivation from the parent keys allows to more efficiently\r\nswitch between children of the same key. Note however that only the immediate\r\nparent of the current key is cached so one cannot use this to go back in the\r\nkeys hierarchy.\r\n\r\nFor ease of use, the user can derive from the root master node key pair\r\n(absolute path) at each card startup, or even before each signature.\r\nThis takes a couple of seconds. So this is better to store intermediate public\r\nkeys hash and check the status to observe the current key pair in use.\r\nThis off-card complex key management is not needed if the signatures volume\r\nis below one thousand per day.\r\n\r\nSee derive and sign methods in the API documentation.\r\n\r\nEC Signature\r\n^^^^^^^^^^^^\r\n\r\nThe derivation of the key pair node can be also possible using the signature\r\ncommand (relative or absolute).\r\n\r\nThe card applet can sign any 256 bits hash provided, using ECDSA with 256k1 EC\r\nparameters. Most of the blockchain system used SHA2-256 to hash the message,\r\nbut this card applet is agnostic from this point, since the signature is performed on\r\na hash provided by the user. Note that this hash needs to be confirmed by the\r\nusers beforehand, when they provide their EC384 signature of this hash.\r\n\r\nThe code to sign with the EC current key node is:\r\n\r\n.. code-block:: python\r\n\r\n signature = card.sign(data_hash, cryptnoxpy.Derivation.CURRENT_KEY)\r\n\r\ndata_hash is a byte-array containing the EC hash to sign using ECDSA ecp256k1:\r\n\r\nThe signature a byte array, encoded as an ASN1 DER sequence of two INTEGER values, r and s.\r\n\r\nSee the sign method in the API documentation for more information.\r\n\r\n=========\r\nChangelog\r\n=========\r\n\r\nAll notable changes to this project will be documented in this file.\r\n\r\nThe format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_\\ ,\r\nand this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.\r\n\r\n`Unreleased <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.3.0...HEAD>`_\r\n-------------------------------------------------------------------------------------\r\n\r\n`2.4.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.3.0...2.4.0>`_ - 2023-01-31\r\n-----------------------------------------------------------------------------------------------\r\n\r\nChanged\r\n^^^^^^^\r\n\r\n- Remote connection message format, not compatible with previous version\r\n\r\n`2.3.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.2.1...2.3.0>`_ - 2022-11-28\r\n-----------------------------------------------------------------------------------------------\r\n\r\nAdded\r\n^^^^^\r\n\r\n- Ability to write and read custom bytes from select command\r\n\r\n`2.2.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.2.0...2.2.1>`_ - 2022-07-14\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n- Installation for Python 3.10\r\n\r\n`2.2.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.1.1...2.2.0>`_ - 2022-07-13\r\n-----------------------------------------------------------------------------------------------\r\n\r\nAdded\r\n^^^^^\r\n\r\n- Support for Python 3.10\r\n\r\nRemoved\r\n^^^^^^^\r\n\r\n- Support for Python 3.6\r\n\r\nFixed\r\n^^^^^\r\n\r\n- `get_public_key` raises an unhandled exception when asking for current key with a derivation path\r\n\r\n`2.1.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.1.0...2.1.1>`_ - 2022-06-13\r\n-----------------------------------------------------------------------------------------------\r\n\r\nAdded\r\n^^^^^\r\n\r\n- Add optional \"hexed\" parameter in get_public_key of cards\r\n\r\n`2.1.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.3...v2.1.0>`_ - 2022-06-01\r\n-----------------------------------------------------------------------------------------------\r\n\r\nAdded\r\n^^^^^\r\n\r\n- Add option for cards from remote connection\r\n\r\n`2.0.3 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.2...v2.0.3>`_ - 2022-03-14\r\n-----------------------------------------------------------------------------------------------\r\n\r\nChanged\r\n^^^^^^^\r\n\r\n- Installation instructions added missing instructions\r\n\r\nFixed\r\n^^^^^\r\n\r\n- `generate_seed` command allowed without previously verifying PIN code\r\n\r\n\r\n`2.0.2 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.1...v2.0.2>`_ - 2022-03-14\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n- `unblock_pin` command shows \"PIN code wasn't authorized\" when card is not locked\r\n\r\n`2.0.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v2.0.0...v2.0.1>`_ - 2022-01-03\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n- Printing debug data during requests call for certificates\r\n\r\n`2.0.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.6...v2.0.0>`_ - 2022-01-03\r\n-----------------------------------------------------------------------------------------------\r\n\r\nAdded\r\n^^^^^\r\n\r\n- New cad type, NFT, with limited functionality intended for keeping one NFT\r\n- Method for checking private key validity\r\n\r\nChanged\r\n^^^^^^^\r\n\r\n- User data read and write property to list\r\n- pyscard on windows fixed to version 2.0.1, in pipenv all OSes.\r\n\r\n`1.1.6 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.5...v1.1.6>`_ - 2021-11-03\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n* Debug parameter not passed when creating card class\r\n\r\n`1.1.5 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.4...v1.1.5>`_ - 2021-10-29\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n* Genuineness check made more resilient to exceptions\r\n\r\n`1.1.4 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.3...v1.1.4>`_ - 2021-10-21\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n* Opening secure channel with G0 card throws exception\r\n\r\n`1.1.3 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.2...v1.1.3>`_ - 2021-10-20\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n* sign operation throws error if PIN code is not provided when user key is used for authentication.\r\n\r\n`1.1.2 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.1...v1.1.2>`_ - 2021-10-07\r\n-----------------------------------------------------------------------------------------------\r\n\r\nFixed\r\n^^^^^\r\n\r\n* Handling of error response from the card for not authenticated\r\n\r\n`1.1.1 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.1.0...v1.1.1>`_ - 2021-10-06\r\n-----------------------------------------------------------------------------------------------\r\n\r\nChanged\r\n^^^^^^^\r\n\r\n* User data size increased to 3600 bytes\r\n\r\nFixed\r\n^^^^^\r\n\r\n* Set PIN-less path didn't convert input path to correct values for card\r\n* Setting PIN-less path and PIN authentication doesn't set flags for indication\r\n* Sign method doesn't fill up given PIN code with 0s up to 9 characters\r\n\r\n`1.1.0 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.0.4...v1.1.0>`_ - 2021-09-24\r\n-----------------------------------------------------------------------------------------------\r\n\r\nAdded\r\n^^^^^\r\n\r\n* Origin property for indicating if the card is original or not or check can't be done.\r\n\r\nChanged\r\n^^^^^^^\r\n\r\n* PyScard updated to 2.0.2\r\n\r\nFixed\r\n^^^^^\r\n\r\n* When card is not initialized seed_source property throws exception. Return `SeedSource.NO_SEED` instead\r\n* When seed is generated in the card the flag for it stays the same\r\n* Operation unlock_pin doesn't raise exception when card is not locked\r\n\r\n`1.0.4 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.0.3...v1.0.4>`_ - 2021-09-09\r\n-----------------------------------------------------------------------------------------------\r\n\r\nChanged\r\n^^^^^^^\r\n\r\n* Improvements in setup\r\n\r\n`1.0.3 <https://github.com/Cryptnox-Software/cryptnoxpy/compare/v1.0.0...v1.0.3>`_ - 2021-09-07\r\n-----------------------------------------------------------------------------------------------\r\n\r\nChanged\r\n^^^^^^^\r\n\r\n* Documentation changed to rst\r\n* Version number stored in the module instead of getting it from pbr\r\n\r\nRemoved\r\n^^^^^^^\r\n\r\n* PBR dependency\r\n\r\nFixed\r\n^^^^^\r\n\r\n* PyPI doesn't install dependencies\r\n\r\n`1.0.0 <https://github.com/Cryptnox-Software/cryptnoxpy/releases/tag/v1.0.0>`_ - 2021-08-20\r\n-------------------------------------------------------------------------------------------\r\n\r\nAdded\r\n^^^^^\r\n\r\n* Card operations\r\n* Pipfile and requirements for setting up environment\r\n* Setup file to install the library\r\n",
"bugtrack_url": null,
"license": "LGPLv3+",
"summary": null,
"version": "2.5.3",
"project_urls": {
"Homepage": "https://www.cryptnox.com/",
"Source Code": "https://github.com/Cryptnox-Software/cryptnoxpy"
},
"split_keywords": [
"python",
" cryptography"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "2f61e87a67ecc658cea4b939baea806b554039b9c083084e69ad347f24bf9a6f",
"md5": "c0a672c8e63bc364e9e2d88b36d703e8",
"sha256": "d430fd50d70adf2248471c65498486445e8338c2aa07d69d0eeb45f4c5ccea00"
},
"downloads": -1,
"filename": "cryptnoxpy-2.5.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c0a672c8e63bc364e9e2d88b36d703e8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.13,>=3.7",
"size": 51594,
"upload_time": "2024-12-19T22:48:14",
"upload_time_iso_8601": "2024-12-19T22:48:14.876973Z",
"url": "https://files.pythonhosted.org/packages/2f/61/e87a67ecc658cea4b939baea806b554039b9c083084e69ad347f24bf9a6f/cryptnoxpy-2.5.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "7c372c6fef203e9609420be8e8fff85a922accbcab30f2e17f1a34ed722353b2",
"md5": "57630a5ee6d0a5bf667676879a0a8f24",
"sha256": "3f9de4aa3c8df4b3cf45403e157deac61dbc24c45286a849e2dd2f9342b40e51"
},
"downloads": -1,
"filename": "cryptnoxpy-2.5.3.tar.gz",
"has_sig": false,
"md5_digest": "57630a5ee6d0a5bf667676879a0a8f24",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.13,>=3.7",
"size": 50328,
"upload_time": "2024-12-19T22:48:17",
"upload_time_iso_8601": "2024-12-19T22:48:17.595572Z",
"url": "https://files.pythonhosted.org/packages/7c/37/2c6fef203e9609420be8e8fff85a922accbcab30f2e17f1a34ed722353b2/cryptnoxpy-2.5.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-19 22:48:17",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Cryptnox-Software",
"github_project": "cryptnoxpy",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [],
"lcname": "cryptnoxpy"
}