cryptnoxpy.card package

Submodules

cryptnoxpy.card.authenticity module

Module containing check for verification of genuineness of a card

cryptnoxpy.card.authenticity.origin(connection: Connection, debug: bool = False) Origin[source]

Check the origin of the card, whether it’s a genuine :param Connection connection: connection to use for the card :param bool debug: print debug messages

Returns:

Whether the card on the connection is genuine

Return type:

Origin

cryptnoxpy.card.authenticity.session_public_key(connection: Connection, debug: bool = False) str[source]

Check if the card in the reader is genuine Cryptnox product

Parameters:
  • connection (Connection) – Connection to use for operation

  • debug (bool) – Prints information about communication

Returns:

Session public key to use opening secure channel

Return type:

str

Raises:

GenuineCheckException – The card is not genuine

cryptnoxpy.card.authenticity.manufacturer_certificate(connection: Connection, debug: bool = False) str[source]

Get the manufacturer certificate from the card in connection.

Parameters:
  • connection (Connection) – Connection to use for operation

  • debug (bool) – Prints information about communication

Returns:

Manufacturer certificate read from the card

Return type:

str

cryptnoxpy.card.base module

Module for keeping information about the card attached to the reader

class cryptnoxpy.card.base.User(name, email)

Bases: tuple

email

Alias for field number 1

name

Alias for field number 0

class cryptnoxpy.card.base.SignatureCheckResult(message, signature)

Bases: tuple

message

Alias for field number 0

signature

Alias for field number 1

class cryptnoxpy.card.base.Base(connection: Connection, serial: int, applet_version: List[int], data: List[int] = None, debug: bool = False)[source]

Bases: object

Object that contains information about the card that is in the reader.

Parameters:
  • connection (Connection) – Connection to use for card initialization

  • debug (bool) – Show debug information to the user.

Variables:
  • applet_version (List[int]) – Version of the applet on the card.

  • serial_number (int) – Serial number of card.

  • session_public_key (str) – Public key of the session.

  • initialized (bool) – The card has been initialized with secrets.

Raises:

CardTypeException – The card in the reader is not a Cryptnox card

PUK_LENGTH = 15
pin_rule = '4-9 digits'
type = 66
user_data = <cryptnoxpy.card.user_data.UserDataBase object>
custom_bits = <cryptnoxpy.card.custom_bits.CustomBitsBase object>
__init__(connection: Connection, serial: int, applet_version: List[int], data: List[int] = None, debug: bool = False)[source]
abstract property select_apdu: List[int]

Value to add to select command to select the applet on the card :rtype: List[int]

Type:

return

abstract property puk_rule: str

Human readable PUK code rule

Returns:

Human readable PUK code rule

Return type:

str

property alive: bool

The connection to the card is established and the card hasn’t been changed :rtype: bool

Type:

return

abstractmethod change_pairing_key(index: int, pairing_key: bytes, puk: str = '') None[source]

Set the pairing key of the card

Parameters:
  • index (int) – Index of the pairing key

  • pairing_key (bytes) – Pairing key to set for the card

  • puk (str) – PUK code of the card

Raises:
change_pin(new_pin: str) None[source]

Change the current pin code of the card to a new pin code.

The method will set the given pin code as the pin code of the card. For it to work the card first must be opened with the current pin code.

Requires:
  • PIN code or challenge-response validated

Parameters:

new_pin (str) – The desired PIN code to be set for the card (4-9 digits).

change_puk(current_puk: str, new_puk: str) None[source]

Change the current pin code of the card to a new pin code.

The method will set the given pin code as the pin code of the card. For it to work the card first must be opened with the current pin code.

Parameters:
  • current_puk (str) – The current PUK code of the card

  • new_puk (str) – The desired PUK code to be set for the card

check_init() None[source]

Check if the initialization has been done on the card.

It can be useful to check if the card is initialized before doing anything else, like asking for pin code from the user.

Raises:

InitializationException – The card is not initialized

abstractmethod derive(key_type: KeyType = KeyType.K1, path: str = '')[source]

Derive key on path and make it the current key in the card

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

Parameters:
  • key_type (KeyType) – Key type to do derive on

  • path (str) – Path on which to do derivation

abstractmethod dual_seed_public_key(pin: str = '') bytes[source]

Get the public key from the card for dual initialization of the cards

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str) – PIN code of card if it was opened with a PIN check

Returns:

Public key and signature that can be sent into the other card

Return type:

bytes

Raises:

DataException – The received data is invalid

abstractmethod dual_seed_load(data: bytes, pin: str = '') None[source]

Load public key and signature from the other card into the card to generate same seed.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • pin (str) – PIN code of card if it was opened with a PIN check

  • data (bytes) – Public key and signature of public key from the other card

abstract property extended_public_key: bool

Extended public key turned on :rtype: bool

Type:

return

abstractmethod generate_random_number(size: int) bytes[source]

Generate random number on the car and return it.

Parameters:

size (int) – Output data size in bytes (between 16 and 64, mod 4)

Returns:

Random number generated by the chip

Return type:

bytes

Raises:

DataValidationException – size in not a number between 16 and 64 or is not divisible by 4

abstractmethod generate_seed(pin: str = '') bytes[source]

Generate a seed directly on the card.

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Returns:

Primary node “m” UID (hash of public key)

Return type:

bytes

Raises:
abstractmethod get_public_key(derivation: Derivation, key_type: KeyType = KeyType.K1, path: str = '', compressed: bool = True) str[source]

Get the public key from the card.

Requires:
  • PIN code or challenge-response validated, except for PIN-less path

  • Seed must exist

Parameters:
  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType) – Key type to use

  • path (str)

  • compressed (bool) – The returned value is in compressed format.

Returns:

The public key for the given path in hexadecimal string format

Return type:

str

Raises:
abstractmethod get_public_key_extended(key_type: KeyType = KeyType.K1, puk: str = '') str[source]

Get the extended public key (xpub) from the card.

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

  • XPUB capability must be enabled (or PUK provided to enable it)

Parameters:
  • key_type (KeyType) – Key type to use (default: KeyType.K1)

  • puk (str) – Optional PUK code to enable XPUB capability

Returns:

Extended public key in hexadecimal string format

Return type:

str

Raises:
get_public_key_clear(derivation: int, path: str = '', compressed: bool = True) bytes[source]

Get the public key within clear channel

Parameters:
  • derivation – Derivation + KeyType (e.g., Derivation.CURRENT_KEY + KeyType.K1)

  • path – Optional BIP path string like “m/44’/0’/0’”

  • compressed – Whether to return compressed format

Returns:

Public key in bytes format

Raises:

exceptions.ReadPublicKeyException – If bad data received

abstractmethod set_pubexport(status: bool, p1: int, puk: str) None[source]

Set pubexport capability (xpub or clear pubkey)

Parameters:
  • status – True to enable, False to disable

  • p1 – 0 for xpub, 1 for clear pubkey

  • puk – PUK code

Raises:
abstractmethod set_xpubread(status: bool, puk: str) None[source]

Set extended public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

abstractmethod set_clearpubkey(status: bool, puk: str) None[source]

Set clear public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

abstractmethod decrypt(p1: int, pubkey: bytes, encrypted_data: bytes = b'', pin: str = '') bytes[source]

Decrypt data using ECIES (Elliptic Curve Integrated Encryption Scheme).

Generates a symmetric secret for simplified ECIES using an EC key in the BIP32 tree. This command is inspired by DECipher in OpenPGP smartcards. This allows asymmetric encryption using a key in the card seed tree. Anyone can encrypt with a public key from the card, and only the (private) key in the card can decrypt.

During the seed loading, the card saves in a dedicated key slot the result of a fixed derivation path. The child EC key used for this command is fixed (relative to a given seed). The path is computed with SLIP17 for the URI “openpgp://cryptnox” with index=0, and equals: m/17’/910196630’/2006168372’/332516148’/580566270’

The symmetric key is computed as SHA2(ECDH): SHA2-256(k.PubKey), where k is the private ECP256r1 key, the “decrypt” key slot.

Parameters:
  • p1 (int) – 0x00 = Output symmetric key, 0x01 = Decrypt data in card

  • pubkey (bytes) – Third party public key in X9.62 uncompressed format (0x04|X|Y, 65 bytes)

  • encrypted_data (bytes) – Encrypted data (required when p1=1, must be 16-byte aligned)

  • pin (str) – PIN code (required if no user key auth, right-padded with 0x00)

Returns:

Symmetric key (p1=0) or decrypted data (p1=1)

Return type:

bytes

Raises:
history(index: int = 0) NamedTuple[source]

Get history of hashes the card has signed regardless of any parameters given to sign

Requires:
  • PIN code or challenge-response validated

Parameters:

index (int) – Index of entry in history

Returns:

Return entry containing signing_counter, representing index of sign call, and hashed_data, the data that was signed

Return type:

NamedTuple

property info: Dict[str, Any]

Get relevant information about the card.

Returns:

Dictionary containing information for the card

Return type:

Dict[str, Any]

init(name: str, email: str, pin: str, puk: str, pairing_secret: bytes = b'Cryptnox Basic CommonPairingData', nfc_sign: bool = False) bytes[source]

Initialize the Cryptnox card.

Initialize the Cryptnox card with the owners name and email address. Set the PIN and PUK codes for authenticating with the card to be able to use it.

Parameters:
  • name (str) – Name of the card owner

  • email (str) – Email of the card owner

  • pin (str) – PIN code that will be used to open the card

  • puk (str) – PUK code that will be used to open the card

  • pairing_secret (bytes) – Pairing secret to use with the card

  • nfc_sign (bool) – Signature command can be used over NFC, only available on certain type

Returns:

Pairing secret

Return type:

bytes

Raises:

InitializationException – There was an issue with initialization

abstract property initialized: bool

Whether the card is initialized :rtype: bool

Type:

return

abstractmethod load_seed(seed: bytes, pin: str = '') None[source]

Load the given seed into the Cryptnox card.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • seed (bytes) – Seed to initialize the card with

  • pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Raises:

KeyGenerationException – Data is not correct

property open: bool

Check if the user has authenticated.

Returns:

Whether the user has authenticated using the PIN code or challenge-response validation

Return type:

bool

property origin: Origin

Check the card origin.

Returns:

Return if the card is original Cryptnox card, fake or there’s an issue getting the information

Return type:

Origin

abstract property pin_authentication: bool

Whether the PIN code can be used for authentication :rtype: bool

Type:

return

abstract property pinless_enabled: bool

Return whether the card has a pinless path :rtype: bool

Type:

return

abstractmethod reset(puk: str) None[source]

Reset the card and return it to factory settings.

Parameters:

puk – PUK code associated with the card

abstract property seed_source: SeedSource

How the seed was generated :rtype: SeedSource

Type:

return

abstractmethod set_pin_authentication(status: bool, puk: str) None[source]

Turn on/off authentication with the PIN code. Other methods can still be used.

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
abstractmethod set_pinless_path(path: str, puk: str) None[source]

Enable working with the card without a PIN on path.

Parameters:
  • path (str) – Path to be available without a PIN code

  • puk (str) – PUK code of the card

Raises:
abstractmethod set_extended_public_key(status: bool, puk: str) None[source]

Turn on/off extended public key output.

Requires:
  • Seed must be loaded

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
abstractmethod sign(data: bytes, derivation: Derivation, key_type: KeyType = KeyType.K1, path: str = '', pin: str = '', filter_eos: bool = False) bytes[source]

Sign the message using given derivation.

Requires:
  • PIN code provided, authenticate with user key by signing same message or PIN-less path used

  • Seed must be loaded

Parameters:
  • data (bytes) – Data to sign

  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType, optional) – Key type to use. Defaults to K1

  • path (str, optional) – Path of the key. If empty use main key

  • pin (str, optional) – PIN code of the card

  • filter_eos (str, optional) – Filter signature so it is valid for EOS network, might take longer. Defaults to False

Returns:

The signature generated by the card in DER common format.

Return type:

bytes

Raises:

DataException – Invalid data received during signature

signature_check(nonce: bytes) SignatureCheckResult[source]

Sign random 32 bytes for validation that private key of public key is on the card.

This call doesn’t increase signature counter and doesn’t go into signature history.

Parameters:

nonce (bytes) – random 16 bytes that will be used to sign

Returns:

Message that was signed and the signature

Return type:

SignatureCheckResult

Raises:
abstract property signing_counter: int

Counter of how many times the card has been used to sign :rtype: int

Type:

return

unblock_pin(puk: str, new_pin: str) None[source]

Verifies the user using the PUK code and sets a new PIN code on the card.

Method should be used when the user has forgotten this/hers PIN code. By entering the PUK code the user verifies his/hers identity and can set the new PIN code on the card. Can be used only if the card is locked.

Requires:
  • User PIN must be locked

  • PIN code authentication must be enabled

Parameters:
  • puk (str) – PUK code for verification of the user, before changing the PIN code.

  • new_pin (str) – The desired PIN code to be set for the card (4-9 digits).

Raises:
abstractmethod user_key_add(slot: SlotIndex, data_info: str, public_key: bytes, puk_code: str, cred_id: bytes = b'') None[source]

Add user public key into the card for user authentication

Parameters:
  • slot (int) – Slot to write the public key to 1 - EC256R1 2 - RSA key, 2048 bits, public exponent must be 65537 3 - FIDO key

  • data_info (bytes) – 64 bytes of user data

  • public_key (bytes) – Public key of the secure element to be used for authentication

  • puk_code (str) – PUK code of the card

  • cred_id (bytes, optional) – Cred id. Used for FIDO2 authentication

Raises:

DataValidationException – Invalid input data

abstractmethod user_key_delete(slot: SlotIndex, puk_code: str) None[source]

Delete the user key from slot and free up for insertion

Parameters:
  • slot (SlotIndex) – Slot to remove the key from

  • puk_code (str) – PUK code of the card

Raises:

DataValidationException – Invalid input data

abstractmethod user_key_info(slot: SlotIndex) Tuple[str, str][source]

Get the description and public key of the user key

Requires:
  • PIN code or challenge-response validated

Parameters:

slot (SlotIndex) – Index of slot for which to fetch the description

Returns:

Description and public key in slot

Return type:

tuple[str, str]

abstractmethod user_key_enabled(slot_index: SlotIndex) bool[source]

Check if user key is present in given slot

Parameters:

slot_index (SlotIndex) – Slot index to check for

Returns:

Whether the user key for slot is present

Return type:

bool

abstractmethod user_key_challenge_response_nonce() bytes[source]

Get 32 bytes random value from the card that is used to open the card with a user key

Take nonce value from the card. Sign it with a third party application, like TPM. Send the signature back into the card using user_key_challenge_response_open()

Returns:

32 bytes random value used as nonce

Return type:

bytes

abstractmethod user_key_challenge_response_open(slot: SlotIndex, signature: bytes) bool[source]

Send the nonce signature to the card to open it for operations, like it was opened by a PIN code

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • signature (bytes) – Signature generated by a third party like TPM.

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

abstractmethod user_key_signature_open(slot: SlotIndex, message: bytes, signature: bytes) bool[source]

Used for opening the card to sign the given message

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • message (bytes) – Message that will be sent to sign operation

  • signature (bytes) – Signature generated by a third party, like TPM, on the same message

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

abstract property valid_key: bool

Check if the card has a valid key

Returns:

Whether the card has a valid key.

Return type:

bool

static valid_pin(pin: str, pin_name: str = 'pin') str[source]

Check if provided pin is valid

Parameters:
  • pin (str) – The pin to check if valid

  • pin_name (str) – Value used in DataValidationException for pin name

Return str:

Provided pin in str format if valid

Raises:

DataValidationException – Provided pin is not valid

abstractmethod static valid_puk(puk: str, puk_name: str = 'puk') str[source]

Check if provided puk is valid

Parameters:
  • puk (str) – The puk to check if valid

  • puk_name (str, optional) – Value used in DataValidationException for puk name. Defaults to: puk

Return str:

Provided puk in str format if valid

Raises:

DataValidationException – Provided puk is not valid

abstractmethod verify_pin(pin: str) None[source]

Check PIN code and open the card for operations that are protected.

The method is sending the PIN code to the card to open it for other operations. If there is an issue an exception will be raised.

Parameters:

pin (str) – PIN code to check against the card.

Raises:

cryptnoxpy.card.basic_g1 module

Module containing class for Basic card of 1st generation

class cryptnoxpy.card.basic_g1.BasicG1(*args, **kwargs)[source]

Bases: Base

Class containing functionality for Basic cards of the 1st generation

select_apdu = [160, 0, 0, 16, 0, 1, 18]
puk_rule = '12 digits and/or letters'
PUK_LENGTH = 12
__init__(*args, **kwargs)[source]
change_pairing_key(index: int, pairing_key: bytes, puk: str = '') None[source]

Set the pairing key of the card

Parameters:
  • index (int) – Index of the pairing key

  • pairing_key (bytes) – Pairing key to set for the card

  • puk (str) – PUK code of the card

Raises:
derive(key_type: KeyType = KeyType.K1, path: str = '')[source]

Derive key on path and make it the current key in the card

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

Parameters:
  • key_type (KeyType) – Key type to do derive on

  • path (str) – Path on which to do derivation

dual_seed_public_key(pin: str = '') bytes[source]

Get the public key from the card for dual initialization of the cards

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str) – PIN code of card if it was opened with a PIN check

Returns:

Public key and signature that can be sent into the other card

Return type:

bytes

Raises:

DataException – The received data is invalid

dual_seed_load(data: bytes, pin: str = '') None[source]

Load public key and signature from the other card into the card to generate same seed.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • pin (str) – PIN code of card if it was opened with a PIN check

  • data (bytes) – Public key and signature of public key from the other card

property extended_public_key: bool

Extended public key turned on :rtype: bool

Type:

return

generate_random_number(size: int) bytes[source]

Generate random number on the car and return it.

Parameters:

size (int) – Output data size in bytes (between 16 and 64, mod 4)

Returns:

Random number generated by the chip

Return type:

bytes

Raises:

DataValidationException – size in not a number between 16 and 64 or is not divisible by 4

generate_seed(pin: str = '') bytes[source]

Generate a seed directly on the card.

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Returns:

Primary node “m” UID (hash of public key)

Return type:

bytes

Raises:
get_manufacturer_certificate()[source]
get_public_key(derivation: Derivation, key_type: KeyType = KeyType.K1, path: str = '', compressed: bool = True, hexed: bool = True) str[source]

Get the public key from the card.

Requires:
  • PIN code or challenge-response validated, except for PIN-less path

  • Seed must exist

Parameters:
  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType) – Key type to use

  • path (str)

  • compressed (bool) – The returned value is in compressed format.

Returns:

The public key for the given path in hexadecimal string format

Return type:

str

Raises:
get_public_key_extended(key_type: KeyType = KeyType.K1, puk: str = '') str[source]

Get the extended public key (xpub) from the card.

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

  • XPUB capability must be enabled (or PUK provided to enable it)

Parameters:
  • key_type (KeyType) – Key type to use (default: KeyType.K1)

  • puk (str) – Optional PUK code to enable XPUB capability

Returns:

Extended public key in hexadecimal string format

Return type:

str

Raises:
get_public_key_clear(derivation: int, path: str = '', compressed: bool = True) bytes[source]

Get the public key within clear channel

Parameters:
  • derivation – Derivation + KeyType (e.g., Derivation.CURRENT_KEY + KeyType.K1)

  • path – Optional BIP path string like “m/44’/0’/0’”

  • compressed – Whether to return compressed format

Returns:

Public key in bytes format

Raises:

exceptions.ReadPublicKeyException – If bad data received

decrypt(p1: int, pubkey: bytes, encrypted_data: bytes = b'', pin: str = '') bytes[source]

Decrypt data using ECIES (Elliptic Curve Integrated Encryption Scheme).

Generates a symmetric secret for simplified ECIES using an EC key in the BIP32 tree. This command is inspired by DECipher in OpenPGP smartcards. This allows asymmetric encryption using a key in the card seed tree. Anyone can encrypt with a public key from the card, and only the (private) key in the card can decrypt.

During the seed loading, the card saves in a dedicated key slot the result of a fixed derivation path. The child EC key used for this command is fixed (relative to a given seed). The path is computed with SLIP17 for the URI “openpgp://cryptnox” with index=0, and equals: m/17’/910196630’/2006168372’/332516148’/580566270’

The symmetric key is computed as SHA2(ECDH): SHA2-256(k.PubKey), where k is the private ECP256r1 key, the “decrypt” key slot.

Parameters:
  • p1 (int) – 0x00 = Output symmetric key, 0x01 = Decrypt data in card

  • pubkey (bytes) – Third party public key in X9.62 uncompressed format (0x04|X|Y, 65 bytes)

  • encrypted_data (bytes) – Encrypted data (required when p1=1, must be 16-byte aligned)

  • pin (str) – PIN code (required if no user key auth, right-padded with 0x00)

Returns:

Symmetric key (p1=0) or decrypted data (p1=1)

Return type:

bytes

Raises:
history(index: int = 0) NamedTuple[source]

Get history of hashes the card has signed regardless of any parameters given to sign

Requires:
  • PIN code or challenge-response validated

Parameters:

index (int) – Index of entry in history

Returns:

Return entry containing signing_counter, representing index of sign call, and hashed_data, the data that was signed

Return type:

NamedTuple

property initialized: bool

Whether the card is initialized :rtype: bool

Type:

return

load_wrapped_seed(seed: bytes, pin: str = '') None[source]
load_seed(seed: bytes, pin: str = '') None[source]

Load the given seed into the Cryptnox card.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • seed (bytes) – Seed to initialize the card with

  • pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Raises:

KeyGenerationException – Data is not correct

property pin_authentication: bool

Whether the PIN code can be used for authentication :rtype: bool

Type:

return

property pinless_enabled: bool

Return whether the card has a pinless path :rtype: bool

Type:

return

reset(puk: str) None[source]

Reset the card and return it to factory settings.

Parameters:

puk – PUK code associated with the card

property seed_source: SeedSource

How the seed was generated :rtype: SeedSource

Type:

return

set_pin_authentication(status: bool, puk: str) None[source]

Turn on/off authentication with the PIN code. Other methods can still be used.

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
set_pinless_path(path: str, puk: str) None[source]

Enable working with the card without a PIN on path.

Parameters:
  • path (str) – Path to be available without a PIN code

  • puk (str) – PUK code of the card

Raises:
set_extended_public_key(status: bool, puk: str) None[source]

Set extended public key capability.

This is a convenience wrapper around set_pubexport(status, 0, puk). Use set_pubexport() directly for more control.

property signing_counter: int

Counter of how many times the card has been used to sign :rtype: int

Type:

return

user_key_add(slot: SlotIndex, data_info: str, public_key: bytes, puk_code: str, cred_id: bytes = b'') None[source]

Add user public key into the card for user authentication

Parameters:
  • slot (int) – Slot to write the public key to 1 - EC256R1 2 - RSA key, 2048 bits, public exponent must be 65537 3 - FIDO key

  • data_info (bytes) – 64 bytes of user data

  • public_key (bytes) – Public key of the secure element to be used for authentication

  • puk_code (str) – PUK code of the card

  • cred_id (bytes, optional) – Cred id. Used for FIDO2 authentication

Raises:

DataValidationException – Invalid input data

user_key_delete(slot: SlotIndex, puk_code: str) None[source]

Delete the user key from slot and free up for insertion

Parameters:
  • slot (SlotIndex) – Slot to remove the key from

  • puk_code (str) – PUK code of the card

Raises:

DataValidationException – Invalid input data

user_key_info(slot: SlotIndex) Tuple[str, str][source]

Get the description and public key of the user key

Requires:
  • PIN code or challenge-response validated

Parameters:

slot (SlotIndex) – Index of slot for which to fetch the description

Returns:

Description and public key in slot

Return type:

tuple[str, str]

user_key_enabled(slot_index: SlotIndex)[source]

Check if user key is present in given slot

Parameters:

slot_index (SlotIndex) – Slot index to check for

Returns:

Whether the user key for slot is present

Return type:

bool

user_key_challenge_response_nonce() bytes[source]

Get 32 bytes random value from the card that is used to open the card with a user key

Take nonce value from the card. Sign it with a third party application, like TPM. Send the signature back into the card using user_key_challenge_response_open()

Returns:

32 bytes random value used as nonce

Return type:

bytes

user_key_challenge_response_open(slot: SlotIndex, signature: bytes) bool[source]

Send the nonce signature to the card to open it for operations, like it was opened by a PIN code

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • signature (bytes) – Signature generated by a third party like TPM.

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

user_key_signature_open(slot: SlotIndex, message: bytes, signature: bytes) bool[source]

Used for opening the card to sign the given message

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • message (bytes) – Message that will be sent to sign operation

  • signature (bytes) – Signature generated by a third party, like TPM, on the same message

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

generate_seed_wrapper(size: int = 2048) bytes[source]
sign_public(key_type: KeyType = KeyType.K1) bytes[source]
sign(data: bytes, derivation: Derivation = Derivation.CURRENT_KEY, key_type: KeyType = KeyType.K1, path: str = '', pin: str = '', filter_eos: bool = False) bytes[source]

Sign the message using given derivation.

Requires:
  • PIN code provided, authenticate with user key by signing same message or PIN-less path used

  • Seed must be loaded

Parameters:
  • data (bytes) – Data to sign

  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType, optional) – Key type to use. Defaults to K1

  • path (str, optional) – Path of the key. If empty use main key

  • pin (str, optional) – PIN code of the card

  • filter_eos (str, optional) – Filter signature so it is valid for EOS network, might take longer. Defaults to False

Returns:

The signature generated by the card in DER common format.

Return type:

bytes

Raises:

DataException – Invalid data received during signature

property valid_key: bool

Check if the card has a valid key

Returns:

Whether the card has a valid key.

Return type:

bool

static valid_puk(puk: str, puk_name: str = 'puk') str[source]

Check if provided puk is valid

Parameters:
  • puk (str) – The puk to check if valid

  • puk_name (str, optional) – Value used in DataValidationException for puk name. Defaults to: puk

Return str:

Provided puk in str format if valid

Raises:

DataValidationException – Provided puk is not valid

verify_pin(pin: str) None[source]

Check PIN code and open the card for operations that are protected.

The method is sending the PIN code to the card to open it for other operations. If there is an issue an exception will be raised.

Parameters:

pin (str) – PIN code to check against the card.

Raises:
set_pubexport(status: bool, p1: int, puk: str) None[source]

Set pubexport capability (xpub or clear pubkey)

Parameters:
  • status – True to enable, False to disable

  • p1 – 0 for xpub, 1 for clear pubkey

  • puk – PUK code

Raises:
set_xpubread(status: bool, puk: str) None[source]

Set extended public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

set_clearpubkey(status: bool, puk: str) None[source]

Set clear public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

cryptnoxpy.card.custom_bits module

Module for making the uer data behave as a list

class cryptnoxpy.card.custom_bits.CustomBitsBase[source]

Bases: object

Class for User Data with all functions returning not implemented in case someone uses it on a card that doesn’t support the feature

class cryptnoxpy.card.custom_bits.CustomBits(data, set_item_callback)[source]

Bases: object

__init__(data, set_item_callback)[source]

cryptnoxpy.card.nft module

Module containing class for NFT card

class cryptnoxpy.card.nft.Nft(*args, **kwargs)[source]

Bases: BasicG1

Class containing functionality for NFT card which has limited capabilities

type = 78
__init__(*args, **kwargs)[source]
derive(key_type: KeyType = KeyType.K1, path: str = '')[source]

Derive key on path and make it the current key in the card

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

Parameters:
  • key_type (KeyType) – Key type to do derive on

  • path (str) – Path on which to do derivation

get_public_key(derivation: Derivation = Derivation.CURRENT_KEY, key_type: KeyType = KeyType.K1, path: str = '', compressed: bool = False, hexed: bool = True) str[source]

Get the public key from the card.

Requires:
  • PIN code or challenge-response validated, except for PIN-less path

  • Seed must exist

Parameters:
  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType) – Key type to use

  • path (str)

  • compressed (bool) – The returned value is in compressed format.

Returns:

The public key for the given path in hexadecimal string format

Return type:

str

Raises:
get_public_key_clear(derivation: int, path: str = '', compressed: bool = True) bytes[source]

Get the public key within clear channel

Parameters:
  • derivation – Derivation + KeyType (e.g., Derivation.CURRENT_KEY + KeyType.K1)

  • path – Optional BIP path string like “m/44’/0’/0’”

  • compressed – Whether to return compressed format

Returns:

Public key in bytes format

Raises:

exceptions.ReadPublicKeyException – If bad data received

set_pubexport(status: bool, p1: int, puk: str) None[source]

Set pubexport capability (xpub or clear pubkey)

Parameters:
  • status – True to enable, False to disable

  • p1 – 0 for xpub, 1 for clear pubkey

  • puk – PUK code

Raises:
set_clearpubkey(status: bool, puk: str) None[source]

Set clear public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

generate_random_number(size: int) bytes[source]

Generate random number on the car and return it.

Parameters:

size (int) – Output data size in bytes (between 16 and 64, mod 4)

Returns:

Random number generated by the chip

Return type:

bytes

Raises:

DataValidationException – size in not a number between 16 and 64 or is not divisible by 4

load_seed(seed: bytes, pin: str = '') None[source]

Load the given seed into the Cryptnox card.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • seed (bytes) – Seed to initialize the card with

  • pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Raises:

KeyGenerationException – Data is not correct

set_pin_authentication(status: bool, puk: str) None[source]

Turn on/off authentication with the PIN code. Other methods can still be used.

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
set_pinless_path(path: str, puk: str) None[source]

Enable working with the card without a PIN on path.

Parameters:
  • path (str) – Path to be available without a PIN code

  • puk (str) – PUK code of the card

Raises:
user_key_add(slot: SlotIndex, data_info: str, public_key: bytes, puk_code: str, cred_id: bytes = b'') None[source]

Add user public key into the card for user authentication

Parameters:
  • slot (int) – Slot to write the public key to 1 - EC256R1 2 - RSA key, 2048 bits, public exponent must be 65537 3 - FIDO key

  • data_info (bytes) – 64 bytes of user data

  • public_key (bytes) – Public key of the secure element to be used for authentication

  • puk_code (str) – PUK code of the card

  • cred_id (bytes, optional) – Cred id. Used for FIDO2 authentication

Raises:

DataValidationException – Invalid input data

user_key_delete(slot: SlotIndex, puk_code: str) None[source]

Delete the user key from slot and free up for insertion

Parameters:
  • slot (SlotIndex) – Slot to remove the key from

  • puk_code (str) – PUK code of the card

Raises:

DataValidationException – Invalid input data

user_key_info(slot: SlotIndex) Tuple[str, str][source]

Get the description and public key of the user key

Requires:
  • PIN code or challenge-response validated

Parameters:

slot (SlotIndex) – Index of slot for which to fetch the description

Returns:

Description and public key in slot

Return type:

tuple[str, str]

user_key_enabled(slot_index: SlotIndex)[source]

Check if user key is present in given slot

Parameters:

slot_index (SlotIndex) – Slot index to check for

Returns:

Whether the user key for slot is present

Return type:

bool

user_key_challenge_response_nonce() bytes[source]

Get 32 bytes random value from the card that is used to open the card with a user key

Take nonce value from the card. Sign it with a third party application, like TPM. Send the signature back into the card using user_key_challenge_response_open()

Returns:

32 bytes random value used as nonce

Return type:

bytes

user_key_challenge_response_open(slot: SlotIndex, signature: bytes) bool[source]

Send the nonce signature to the card to open it for operations, like it was opened by a PIN code

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • signature (bytes) – Signature generated by a third party like TPM.

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

user_key_signature_open(slot: SlotIndex, message: bytes, signature: bytes) bool[source]

Used for opening the card to sign the given message

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • message (bytes) – Message that will be sent to sign operation

  • signature (bytes) – Signature generated by a third party, like TPM, on the same message

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

signature_check(nonce: bytes) SignatureCheckResult[source]

Sign random 32 bytes for validation that private key of public key is on the card.

This call doesn’t increase signature counter and doesn’t go into signature history.

Parameters:

nonce (bytes) – random 16 bytes that will be used to sign

Returns:

Message that was signed and the signature

Return type:

SignatureCheckResult

Raises:

cryptnoxpy.card.user_data module

Module for making the uer data behave as a list

class cryptnoxpy.card.user_data.UserDataBase[source]

Bases: object

Class for User Data with all functions returning not implemented in case someone uses it on a card that doesn’t support the feature

class cryptnoxpy.card.user_data.UserData(card, slot_offset: int = 0, reading_index_offset: int = 0)[source]

Bases: object

User data that behaves as a list and can fetch different user slots from the card

__init__(card, slot_offset: int = 0, reading_index_offset: int = 0)[source]

Module contents

Module that contains classes for various Cryptnox cards.

class cryptnoxpy.card.Base(connection: Connection, serial: int, applet_version: List[int], data: List[int] = None, debug: bool = False)[source]

Bases: object

Object that contains information about the card that is in the reader.

Parameters:
  • connection (Connection) – Connection to use for card initialization

  • debug (bool) – Show debug information to the user.

Variables:
  • applet_version (List[int]) – Version of the applet on the card.

  • serial_number (int) – Serial number of card.

  • session_public_key (str) – Public key of the session.

  • initialized (bool) – The card has been initialized with secrets.

Raises:

CardTypeException – The card in the reader is not a Cryptnox card

PUK_LENGTH = 15
__init__(connection: Connection, serial: int, applet_version: List[int], data: List[int] = None, debug: bool = False)[source]
property alive: bool

The connection to the card is established and the card hasn’t been changed :rtype: bool

Type:

return

abstractmethod change_pairing_key(index: int, pairing_key: bytes, puk: str = '') None[source]

Set the pairing key of the card

Parameters:
  • index (int) – Index of the pairing key

  • pairing_key (bytes) – Pairing key to set for the card

  • puk (str) – PUK code of the card

Raises:
change_pin(new_pin: str) None[source]

Change the current pin code of the card to a new pin code.

The method will set the given pin code as the pin code of the card. For it to work the card first must be opened with the current pin code.

Requires:
  • PIN code or challenge-response validated

Parameters:

new_pin (str) – The desired PIN code to be set for the card (4-9 digits).

change_puk(current_puk: str, new_puk: str) None[source]

Change the current pin code of the card to a new pin code.

The method will set the given pin code as the pin code of the card. For it to work the card first must be opened with the current pin code.

Parameters:
  • current_puk (str) – The current PUK code of the card

  • new_puk (str) – The desired PUK code to be set for the card

check_init() None[source]

Check if the initialization has been done on the card.

It can be useful to check if the card is initialized before doing anything else, like asking for pin code from the user.

Raises:

InitializationException – The card is not initialized

custom_bits = <cryptnoxpy.card.custom_bits.CustomBitsBase object>
abstractmethod decrypt(p1: int, pubkey: bytes, encrypted_data: bytes = b'', pin: str = '') bytes[source]

Decrypt data using ECIES (Elliptic Curve Integrated Encryption Scheme).

Generates a symmetric secret for simplified ECIES using an EC key in the BIP32 tree. This command is inspired by DECipher in OpenPGP smartcards. This allows asymmetric encryption using a key in the card seed tree. Anyone can encrypt with a public key from the card, and only the (private) key in the card can decrypt.

During the seed loading, the card saves in a dedicated key slot the result of a fixed derivation path. The child EC key used for this command is fixed (relative to a given seed). The path is computed with SLIP17 for the URI “openpgp://cryptnox” with index=0, and equals: m/17’/910196630’/2006168372’/332516148’/580566270’

The symmetric key is computed as SHA2(ECDH): SHA2-256(k.PubKey), where k is the private ECP256r1 key, the “decrypt” key slot.

Parameters:
  • p1 (int) – 0x00 = Output symmetric key, 0x01 = Decrypt data in card

  • pubkey (bytes) – Third party public key in X9.62 uncompressed format (0x04|X|Y, 65 bytes)

  • encrypted_data (bytes) – Encrypted data (required when p1=1, must be 16-byte aligned)

  • pin (str) – PIN code (required if no user key auth, right-padded with 0x00)

Returns:

Symmetric key (p1=0) or decrypted data (p1=1)

Return type:

bytes

Raises:
abstractmethod derive(key_type: KeyType = KeyType.K1, path: str = '')[source]

Derive key on path and make it the current key in the card

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

Parameters:
  • key_type (KeyType) – Key type to do derive on

  • path (str) – Path on which to do derivation

abstractmethod dual_seed_load(data: bytes, pin: str = '') None[source]

Load public key and signature from the other card into the card to generate same seed.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • pin (str) – PIN code of card if it was opened with a PIN check

  • data (bytes) – Public key and signature of public key from the other card

abstractmethod dual_seed_public_key(pin: str = '') bytes[source]

Get the public key from the card for dual initialization of the cards

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str) – PIN code of card if it was opened with a PIN check

Returns:

Public key and signature that can be sent into the other card

Return type:

bytes

Raises:

DataException – The received data is invalid

abstract property extended_public_key: bool

Extended public key turned on :rtype: bool

Type:

return

abstractmethod generate_random_number(size: int) bytes[source]

Generate random number on the car and return it.

Parameters:

size (int) – Output data size in bytes (between 16 and 64, mod 4)

Returns:

Random number generated by the chip

Return type:

bytes

Raises:

DataValidationException – size in not a number between 16 and 64 or is not divisible by 4

abstractmethod generate_seed(pin: str = '') bytes[source]

Generate a seed directly on the card.

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Returns:

Primary node “m” UID (hash of public key)

Return type:

bytes

Raises:
abstractmethod get_public_key(derivation: Derivation, key_type: KeyType = KeyType.K1, path: str = '', compressed: bool = True) str[source]

Get the public key from the card.

Requires:
  • PIN code or challenge-response validated, except for PIN-less path

  • Seed must exist

Parameters:
  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType) – Key type to use

  • path (str)

  • compressed (bool) – The returned value is in compressed format.

Returns:

The public key for the given path in hexadecimal string format

Return type:

str

Raises:
get_public_key_clear(derivation: int, path: str = '', compressed: bool = True) bytes[source]

Get the public key within clear channel

Parameters:
  • derivation – Derivation + KeyType (e.g., Derivation.CURRENT_KEY + KeyType.K1)

  • path – Optional BIP path string like “m/44’/0’/0’”

  • compressed – Whether to return compressed format

Returns:

Public key in bytes format

Raises:

exceptions.ReadPublicKeyException – If bad data received

abstractmethod get_public_key_extended(key_type: KeyType = KeyType.K1, puk: str = '') str[source]

Get the extended public key (xpub) from the card.

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

  • XPUB capability must be enabled (or PUK provided to enable it)

Parameters:
  • key_type (KeyType) – Key type to use (default: KeyType.K1)

  • puk (str) – Optional PUK code to enable XPUB capability

Returns:

Extended public key in hexadecimal string format

Return type:

str

Raises:
history(index: int = 0) NamedTuple[source]

Get history of hashes the card has signed regardless of any parameters given to sign

Requires:
  • PIN code or challenge-response validated

Parameters:

index (int) – Index of entry in history

Returns:

Return entry containing signing_counter, representing index of sign call, and hashed_data, the data that was signed

Return type:

NamedTuple

property info: Dict[str, Any]

Get relevant information about the card.

Returns:

Dictionary containing information for the card

Return type:

Dict[str, Any]

init(name: str, email: str, pin: str, puk: str, pairing_secret: bytes = b'Cryptnox Basic CommonPairingData', nfc_sign: bool = False) bytes[source]

Initialize the Cryptnox card.

Initialize the Cryptnox card with the owners name and email address. Set the PIN and PUK codes for authenticating with the card to be able to use it.

Parameters:
  • name (str) – Name of the card owner

  • email (str) – Email of the card owner

  • pin (str) – PIN code that will be used to open the card

  • puk (str) – PUK code that will be used to open the card

  • pairing_secret (bytes) – Pairing secret to use with the card

  • nfc_sign (bool) – Signature command can be used over NFC, only available on certain type

Returns:

Pairing secret

Return type:

bytes

Raises:

InitializationException – There was an issue with initialization

abstract property initialized: bool

Whether the card is initialized :rtype: bool

Type:

return

abstractmethod load_seed(seed: bytes, pin: str = '') None[source]

Load the given seed into the Cryptnox card.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • seed (bytes) – Seed to initialize the card with

  • pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Raises:

KeyGenerationException – Data is not correct

property open: bool

Check if the user has authenticated.

Returns:

Whether the user has authenticated using the PIN code or challenge-response validation

Return type:

bool

property origin: Origin

Check the card origin.

Returns:

Return if the card is original Cryptnox card, fake or there’s an issue getting the information

Return type:

Origin

abstract property pin_authentication: bool

Whether the PIN code can be used for authentication :rtype: bool

Type:

return

pin_rule = '4-9 digits'
abstract property pinless_enabled: bool

Return whether the card has a pinless path :rtype: bool

Type:

return

abstract property puk_rule: str

Human readable PUK code rule

Returns:

Human readable PUK code rule

Return type:

str

abstractmethod reset(puk: str) None[source]

Reset the card and return it to factory settings.

Parameters:

puk – PUK code associated with the card

abstract property seed_source: SeedSource

How the seed was generated :rtype: SeedSource

Type:

return

abstract property select_apdu: List[int]

Value to add to select command to select the applet on the card :rtype: List[int]

Type:

return

abstractmethod set_clearpubkey(status: bool, puk: str) None[source]

Set clear public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

abstractmethod set_extended_public_key(status: bool, puk: str) None[source]

Turn on/off extended public key output.

Requires:
  • Seed must be loaded

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
abstractmethod set_pin_authentication(status: bool, puk: str) None[source]

Turn on/off authentication with the PIN code. Other methods can still be used.

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
abstractmethod set_pinless_path(path: str, puk: str) None[source]

Enable working with the card without a PIN on path.

Parameters:
  • path (str) – Path to be available without a PIN code

  • puk (str) – PUK code of the card

Raises:
abstractmethod set_pubexport(status: bool, p1: int, puk: str) None[source]

Set pubexport capability (xpub or clear pubkey)

Parameters:
  • status – True to enable, False to disable

  • p1 – 0 for xpub, 1 for clear pubkey

  • puk – PUK code

Raises:
abstractmethod set_xpubread(status: bool, puk: str) None[source]

Set extended public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

abstractmethod sign(data: bytes, derivation: Derivation, key_type: KeyType = KeyType.K1, path: str = '', pin: str = '', filter_eos: bool = False) bytes[source]

Sign the message using given derivation.

Requires:
  • PIN code provided, authenticate with user key by signing same message or PIN-less path used

  • Seed must be loaded

Parameters:
  • data (bytes) – Data to sign

  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType, optional) – Key type to use. Defaults to K1

  • path (str, optional) – Path of the key. If empty use main key

  • pin (str, optional) – PIN code of the card

  • filter_eos (str, optional) – Filter signature so it is valid for EOS network, might take longer. Defaults to False

Returns:

The signature generated by the card in DER common format.

Return type:

bytes

Raises:

DataException – Invalid data received during signature

signature_check(nonce: bytes) SignatureCheckResult[source]

Sign random 32 bytes for validation that private key of public key is on the card.

This call doesn’t increase signature counter and doesn’t go into signature history.

Parameters:

nonce (bytes) – random 16 bytes that will be used to sign

Returns:

Message that was signed and the signature

Return type:

SignatureCheckResult

Raises:
abstract property signing_counter: int

Counter of how many times the card has been used to sign :rtype: int

Type:

return

type = 66
unblock_pin(puk: str, new_pin: str) None[source]

Verifies the user using the PUK code and sets a new PIN code on the card.

Method should be used when the user has forgotten this/hers PIN code. By entering the PUK code the user verifies his/hers identity and can set the new PIN code on the card. Can be used only if the card is locked.

Requires:
  • User PIN must be locked

  • PIN code authentication must be enabled

Parameters:
  • puk (str) – PUK code for verification of the user, before changing the PIN code.

  • new_pin (str) – The desired PIN code to be set for the card (4-9 digits).

Raises:
user_data = <cryptnoxpy.card.user_data.UserDataBase object>
abstractmethod user_key_add(slot: SlotIndex, data_info: str, public_key: bytes, puk_code: str, cred_id: bytes = b'') None[source]

Add user public key into the card for user authentication

Parameters:
  • slot (int) – Slot to write the public key to 1 - EC256R1 2 - RSA key, 2048 bits, public exponent must be 65537 3 - FIDO key

  • data_info (bytes) – 64 bytes of user data

  • public_key (bytes) – Public key of the secure element to be used for authentication

  • puk_code (str) – PUK code of the card

  • cred_id (bytes, optional) – Cred id. Used for FIDO2 authentication

Raises:

DataValidationException – Invalid input data

abstractmethod user_key_challenge_response_nonce() bytes[source]

Get 32 bytes random value from the card that is used to open the card with a user key

Take nonce value from the card. Sign it with a third party application, like TPM. Send the signature back into the card using user_key_challenge_response_open()

Returns:

32 bytes random value used as nonce

Return type:

bytes

abstractmethod user_key_challenge_response_open(slot: SlotIndex, signature: bytes) bool[source]

Send the nonce signature to the card to open it for operations, like it was opened by a PIN code

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • signature (bytes) – Signature generated by a third party like TPM.

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

abstractmethod user_key_delete(slot: SlotIndex, puk_code: str) None[source]

Delete the user key from slot and free up for insertion

Parameters:
  • slot (SlotIndex) – Slot to remove the key from

  • puk_code (str) – PUK code of the card

Raises:

DataValidationException – Invalid input data

abstractmethod user_key_enabled(slot_index: SlotIndex) bool[source]

Check if user key is present in given slot

Parameters:

slot_index (SlotIndex) – Slot index to check for

Returns:

Whether the user key for slot is present

Return type:

bool

abstractmethod user_key_info(slot: SlotIndex) Tuple[str, str][source]

Get the description and public key of the user key

Requires:
  • PIN code or challenge-response validated

Parameters:

slot (SlotIndex) – Index of slot for which to fetch the description

Returns:

Description and public key in slot

Return type:

tuple[str, str]

abstractmethod user_key_signature_open(slot: SlotIndex, message: bytes, signature: bytes) bool[source]

Used for opening the card to sign the given message

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • message (bytes) – Message that will be sent to sign operation

  • signature (bytes) – Signature generated by a third party, like TPM, on the same message

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

abstract property valid_key: bool

Check if the card has a valid key

Returns:

Whether the card has a valid key.

Return type:

bool

static valid_pin(pin: str, pin_name: str = 'pin') str[source]

Check if provided pin is valid

Parameters:
  • pin (str) – The pin to check if valid

  • pin_name (str) – Value used in DataValidationException for pin name

Return str:

Provided pin in str format if valid

Raises:

DataValidationException – Provided pin is not valid

abstractmethod static valid_puk(puk: str, puk_name: str = 'puk') str[source]

Check if provided puk is valid

Parameters:
  • puk (str) – The puk to check if valid

  • puk_name (str, optional) – Value used in DataValidationException for puk name. Defaults to: puk

Return str:

Provided puk in str format if valid

Raises:

DataValidationException – Provided puk is not valid

abstractmethod verify_pin(pin: str) None[source]

Check PIN code and open the card for operations that are protected.

The method is sending the PIN code to the card to open it for other operations. If there is an issue an exception will be raised.

Parameters:

pin (str) – PIN code to check against the card.

Raises:
applet_version: List[int]
serial_number: int
auth_type: AuthType
class cryptnoxpy.card.BasicG1(*args, **kwargs)[source]

Bases: Base

Class containing functionality for Basic cards of the 1st generation

PUK_LENGTH = 12
__init__(*args, **kwargs)[source]
change_pairing_key(index: int, pairing_key: bytes, puk: str = '') None[source]

Set the pairing key of the card

Parameters:
  • index (int) – Index of the pairing key

  • pairing_key (bytes) – Pairing key to set for the card

  • puk (str) – PUK code of the card

Raises:
decrypt(p1: int, pubkey: bytes, encrypted_data: bytes = b'', pin: str = '') bytes[source]

Decrypt data using ECIES (Elliptic Curve Integrated Encryption Scheme).

Generates a symmetric secret for simplified ECIES using an EC key in the BIP32 tree. This command is inspired by DECipher in OpenPGP smartcards. This allows asymmetric encryption using a key in the card seed tree. Anyone can encrypt with a public key from the card, and only the (private) key in the card can decrypt.

During the seed loading, the card saves in a dedicated key slot the result of a fixed derivation path. The child EC key used for this command is fixed (relative to a given seed). The path is computed with SLIP17 for the URI “openpgp://cryptnox” with index=0, and equals: m/17’/910196630’/2006168372’/332516148’/580566270’

The symmetric key is computed as SHA2(ECDH): SHA2-256(k.PubKey), where k is the private ECP256r1 key, the “decrypt” key slot.

Parameters:
  • p1 (int) – 0x00 = Output symmetric key, 0x01 = Decrypt data in card

  • pubkey (bytes) – Third party public key in X9.62 uncompressed format (0x04|X|Y, 65 bytes)

  • encrypted_data (bytes) – Encrypted data (required when p1=1, must be 16-byte aligned)

  • pin (str) – PIN code (required if no user key auth, right-padded with 0x00)

Returns:

Symmetric key (p1=0) or decrypted data (p1=1)

Return type:

bytes

Raises:
derive(key_type: KeyType = KeyType.K1, path: str = '')[source]

Derive key on path and make it the current key in the card

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

Parameters:
  • key_type (KeyType) – Key type to do derive on

  • path (str) – Path on which to do derivation

dual_seed_load(data: bytes, pin: str = '') None[source]

Load public key and signature from the other card into the card to generate same seed.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • pin (str) – PIN code of card if it was opened with a PIN check

  • data (bytes) – Public key and signature of public key from the other card

dual_seed_public_key(pin: str = '') bytes[source]

Get the public key from the card for dual initialization of the cards

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str) – PIN code of card if it was opened with a PIN check

Returns:

Public key and signature that can be sent into the other card

Return type:

bytes

Raises:

DataException – The received data is invalid

property extended_public_key: bool

Extended public key turned on :rtype: bool

Type:

return

generate_random_number(size: int) bytes[source]

Generate random number on the car and return it.

Parameters:

size (int) – Output data size in bytes (between 16 and 64, mod 4)

Returns:

Random number generated by the chip

Return type:

bytes

Raises:

DataValidationException – size in not a number between 16 and 64 or is not divisible by 4

generate_seed(pin: str = '') bytes[source]

Generate a seed directly on the card.

Requires:
  • PIN code or challenge-response validated

Parameters:

pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Returns:

Primary node “m” UID (hash of public key)

Return type:

bytes

Raises:
generate_seed_wrapper(size: int = 2048) bytes[source]
get_manufacturer_certificate()[source]
get_public_key(derivation: Derivation, key_type: KeyType = KeyType.K1, path: str = '', compressed: bool = True, hexed: bool = True) str[source]

Get the public key from the card.

Requires:
  • PIN code or challenge-response validated, except for PIN-less path

  • Seed must exist

Parameters:
  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType) – Key type to use

  • path (str)

  • compressed (bool) – The returned value is in compressed format.

Returns:

The public key for the given path in hexadecimal string format

Return type:

str

Raises:
get_public_key_clear(derivation: int, path: str = '', compressed: bool = True) bytes[source]

Get the public key within clear channel

Parameters:
  • derivation – Derivation + KeyType (e.g., Derivation.CURRENT_KEY + KeyType.K1)

  • path – Optional BIP path string like “m/44’/0’/0’”

  • compressed – Whether to return compressed format

Returns:

Public key in bytes format

Raises:

exceptions.ReadPublicKeyException – If bad data received

get_public_key_extended(key_type: KeyType = KeyType.K1, puk: str = '') str[source]

Get the extended public key (xpub) from the card.

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

  • XPUB capability must be enabled (or PUK provided to enable it)

Parameters:
  • key_type (KeyType) – Key type to use (default: KeyType.K1)

  • puk (str) – Optional PUK code to enable XPUB capability

Returns:

Extended public key in hexadecimal string format

Return type:

str

Raises:
history(index: int = 0) NamedTuple[source]

Get history of hashes the card has signed regardless of any parameters given to sign

Requires:
  • PIN code or challenge-response validated

Parameters:

index (int) – Index of entry in history

Returns:

Return entry containing signing_counter, representing index of sign call, and hashed_data, the data that was signed

Return type:

NamedTuple

property initialized: bool

Whether the card is initialized :rtype: bool

Type:

return

load_seed(seed: bytes, pin: str = '') None[source]

Load the given seed into the Cryptnox card.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • seed (bytes) – Seed to initialize the card with

  • pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Raises:

KeyGenerationException – Data is not correct

load_wrapped_seed(seed: bytes, pin: str = '') None[source]
property pin_authentication: bool

Whether the PIN code can be used for authentication :rtype: bool

Type:

return

property pinless_enabled: bool

Return whether the card has a pinless path :rtype: bool

Type:

return

puk_rule = '12 digits and/or letters'
reset(puk: str) None[source]

Reset the card and return it to factory settings.

Parameters:

puk – PUK code associated with the card

property seed_source: SeedSource

How the seed was generated :rtype: SeedSource

Type:

return

select_apdu = [160, 0, 0, 16, 0, 1, 18]
set_clearpubkey(status: bool, puk: str) None[source]

Set clear public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

set_extended_public_key(status: bool, puk: str) None[source]

Set extended public key capability.

This is a convenience wrapper around set_pubexport(status, 0, puk). Use set_pubexport() directly for more control.

set_pin_authentication(status: bool, puk: str) None[source]

Turn on/off authentication with the PIN code. Other methods can still be used.

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
set_pinless_path(path: str, puk: str) None[source]

Enable working with the card without a PIN on path.

Parameters:
  • path (str) – Path to be available without a PIN code

  • puk (str) – PUK code of the card

Raises:
set_pubexport(status: bool, p1: int, puk: str) None[source]

Set pubexport capability (xpub or clear pubkey)

Parameters:
  • status – True to enable, False to disable

  • p1 – 0 for xpub, 1 for clear pubkey

  • puk – PUK code

Raises:
set_xpubread(status: bool, puk: str) None[source]

Set extended public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

sign(data: bytes, derivation: Derivation = Derivation.CURRENT_KEY, key_type: KeyType = KeyType.K1, path: str = '', pin: str = '', filter_eos: bool = False) bytes[source]

Sign the message using given derivation.

Requires:
  • PIN code provided, authenticate with user key by signing same message or PIN-less path used

  • Seed must be loaded

Parameters:
  • data (bytes) – Data to sign

  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType, optional) – Key type to use. Defaults to K1

  • path (str, optional) – Path of the key. If empty use main key

  • pin (str, optional) – PIN code of the card

  • filter_eos (str, optional) – Filter signature so it is valid for EOS network, might take longer. Defaults to False

Returns:

The signature generated by the card in DER common format.

Return type:

bytes

Raises:

DataException – Invalid data received during signature

sign_public(key_type: KeyType = KeyType.K1) bytes[source]
property signing_counter: int

Counter of how many times the card has been used to sign :rtype: int

Type:

return

user_key_add(slot: SlotIndex, data_info: str, public_key: bytes, puk_code: str, cred_id: bytes = b'') None[source]

Add user public key into the card for user authentication

Parameters:
  • slot (int) – Slot to write the public key to 1 - EC256R1 2 - RSA key, 2048 bits, public exponent must be 65537 3 - FIDO key

  • data_info (bytes) – 64 bytes of user data

  • public_key (bytes) – Public key of the secure element to be used for authentication

  • puk_code (str) – PUK code of the card

  • cred_id (bytes, optional) – Cred id. Used for FIDO2 authentication

Raises:

DataValidationException – Invalid input data

user_key_challenge_response_nonce() bytes[source]

Get 32 bytes random value from the card that is used to open the card with a user key

Take nonce value from the card. Sign it with a third party application, like TPM. Send the signature back into the card using user_key_challenge_response_open()

Returns:

32 bytes random value used as nonce

Return type:

bytes

user_key_challenge_response_open(slot: SlotIndex, signature: bytes) bool[source]

Send the nonce signature to the card to open it for operations, like it was opened by a PIN code

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • signature (bytes) – Signature generated by a third party like TPM.

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

user_key_delete(slot: SlotIndex, puk_code: str) None[source]

Delete the user key from slot and free up for insertion

Parameters:
  • slot (SlotIndex) – Slot to remove the key from

  • puk_code (str) – PUK code of the card

Raises:

DataValidationException – Invalid input data

user_key_enabled(slot_index: SlotIndex)[source]

Check if user key is present in given slot

Parameters:

slot_index (SlotIndex) – Slot index to check for

Returns:

Whether the user key for slot is present

Return type:

bool

user_key_info(slot: SlotIndex) Tuple[str, str][source]

Get the description and public key of the user key

Requires:
  • PIN code or challenge-response validated

Parameters:

slot (SlotIndex) – Index of slot for which to fetch the description

Returns:

Description and public key in slot

Return type:

tuple[str, str]

user_key_signature_open(slot: SlotIndex, message: bytes, signature: bytes) bool[source]

Used for opening the card to sign the given message

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • message (bytes) – Message that will be sent to sign operation

  • signature (bytes) – Signature generated by a third party, like TPM, on the same message

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

property valid_key: bool

Check if the card has a valid key

Returns:

Whether the card has a valid key.

Return type:

bool

static valid_puk(puk: str, puk_name: str = 'puk') str[source]

Check if provided puk is valid

Parameters:
  • puk (str) – The puk to check if valid

  • puk_name (str, optional) – Value used in DataValidationException for puk name. Defaults to: puk

Return str:

Provided puk in str format if valid

Raises:

DataValidationException – Provided puk is not valid

verify_pin(pin: str) None[source]

Check PIN code and open the card for operations that are protected.

The method is sending the PIN code to the card to open it for other operations. If there is an issue an exception will be raised.

Parameters:

pin (str) – PIN code to check against the card.

Raises:
applet_version: List[int]
serial_number: int
auth_type: AuthType
class cryptnoxpy.card.Nft(*args, **kwargs)[source]

Bases: BasicG1

Class containing functionality for NFT card which has limited capabilities

__init__(*args, **kwargs)[source]
derive(key_type: KeyType = KeyType.K1, path: str = '')[source]

Derive key on path and make it the current key in the card

Requires:
  • PIN code or challenge-response validated

  • Seed must exist

Parameters:
  • key_type (KeyType) – Key type to do derive on

  • path (str) – Path on which to do derivation

generate_random_number(size: int) bytes[source]

Generate random number on the car and return it.

Parameters:

size (int) – Output data size in bytes (between 16 and 64, mod 4)

Returns:

Random number generated by the chip

Return type:

bytes

Raises:

DataValidationException – size in not a number between 16 and 64 or is not divisible by 4

get_public_key(derivation: Derivation = Derivation.CURRENT_KEY, key_type: KeyType = KeyType.K1, path: str = '', compressed: bool = False, hexed: bool = True) str[source]

Get the public key from the card.

Requires:
  • PIN code or challenge-response validated, except for PIN-less path

  • Seed must exist

Parameters:
  • derivation (Derivation) – Derivation to use.

  • key_type (KeyType) – Key type to use

  • path (str)

  • compressed (bool) – The returned value is in compressed format.

Returns:

The public key for the given path in hexadecimal string format

Return type:

str

Raises:
get_public_key_clear(derivation: int, path: str = '', compressed: bool = True) bytes[source]

Get the public key within clear channel

Parameters:
  • derivation – Derivation + KeyType (e.g., Derivation.CURRENT_KEY + KeyType.K1)

  • path – Optional BIP path string like “m/44’/0’/0’”

  • compressed – Whether to return compressed format

Returns:

Public key in bytes format

Raises:

exceptions.ReadPublicKeyException – If bad data received

load_seed(seed: bytes, pin: str = '') None[source]

Load the given seed into the Cryptnox card.

Requires:
  • PIN code or challenge-response validated

Parameters:
  • seed (bytes) – Seed to initialize the card with

  • pin (str, optional) – PIN code of the card. Can be empty if card is opened with challenge-response validation

Raises:

KeyGenerationException – Data is not correct

set_clearpubkey(status: bool, puk: str) None[source]

Set clear public key read capability

Parameters:
  • status – True to enable, False to disable

  • puk – PUK code

set_pin_authentication(status: bool, puk: str) None[source]

Turn on/off authentication with the PIN code. Other methods can still be used.

Parameters:
  • status (bool) – Status of PIN authentication

  • puk (str) – PUK code associated with the card

Raises:
set_pinless_path(path: str, puk: str) None[source]

Enable working with the card without a PIN on path.

Parameters:
  • path (str) – Path to be available without a PIN code

  • puk (str) – PUK code of the card

Raises:
set_pubexport(status: bool, p1: int, puk: str) None[source]

Set pubexport capability (xpub or clear pubkey)

Parameters:
  • status – True to enable, False to disable

  • p1 – 0 for xpub, 1 for clear pubkey

  • puk – PUK code

Raises:
signature_check(nonce: bytes) SignatureCheckResult[source]

Sign random 32 bytes for validation that private key of public key is on the card.

This call doesn’t increase signature counter and doesn’t go into signature history.

Parameters:

nonce (bytes) – random 16 bytes that will be used to sign

Returns:

Message that was signed and the signature

Return type:

SignatureCheckResult

Raises:
type = 78
user_key_add(slot: SlotIndex, data_info: str, public_key: bytes, puk_code: str, cred_id: bytes = b'') None[source]

Add user public key into the card for user authentication

Parameters:
  • slot (int) – Slot to write the public key to 1 - EC256R1 2 - RSA key, 2048 bits, public exponent must be 65537 3 - FIDO key

  • data_info (bytes) – 64 bytes of user data

  • public_key (bytes) – Public key of the secure element to be used for authentication

  • puk_code (str) – PUK code of the card

  • cred_id (bytes, optional) – Cred id. Used for FIDO2 authentication

Raises:

DataValidationException – Invalid input data

user_key_challenge_response_nonce() bytes[source]

Get 32 bytes random value from the card that is used to open the card with a user key

Take nonce value from the card. Sign it with a third party application, like TPM. Send the signature back into the card using user_key_challenge_response_open()

Returns:

32 bytes random value used as nonce

Return type:

bytes

user_key_challenge_response_open(slot: SlotIndex, signature: bytes) bool[source]

Send the nonce signature to the card to open it for operations, like it was opened by a PIN code

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • signature (bytes) – Signature generated by a third party like TPM.

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

user_key_delete(slot: SlotIndex, puk_code: str) None[source]

Delete the user key from slot and free up for insertion

Parameters:
  • slot (SlotIndex) – Slot to remove the key from

  • puk_code (str) – PUK code of the card

Raises:

DataValidationException – Invalid input data

user_key_enabled(slot_index: SlotIndex)[source]

Check if user key is present in given slot

Parameters:

slot_index (SlotIndex) – Slot index to check for

Returns:

Whether the user key for slot is present

Return type:

bool

user_key_info(slot: SlotIndex) Tuple[str, str][source]

Get the description and public key of the user key

Requires:
  • PIN code or challenge-response validated

Parameters:

slot (SlotIndex) – Index of slot for which to fetch the description

Returns:

Description and public key in slot

Return type:

tuple[str, str]

user_key_signature_open(slot: SlotIndex, message: bytes, signature: bytes) bool[source]

Used for opening the card to sign the given message

Parameters:
  • slot (SlotIndex) – Slot to use to open the card

  • message (bytes) – Message that will be sent to sign operation

  • signature (bytes) – Signature generated by a third party, like TPM, on the same message

Returns:

Whether the challenge response authentication succeeded

Return type:

bool

Raises:

DataValidationException – invalid input data

applet_version: List[int]
serial_number: int
auth_type: AuthType

The cryptnoxpy.card package contains classes for various Cryptnox card types and exports:

class cryptnoxpy.card.Base[source]

Base card interface class. See cryptnoxpy.card.base.Base for details.

class cryptnoxpy.card.BasicG1[source]

Basic Generation 1 card implementation. See cryptnoxpy.card.basic_g1.BasicG1 for details.

class cryptnoxpy.card.Nft[source]

NFT card implementation. See cryptnoxpy.card.nft.Nft for details.