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:
- 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:
objectObject 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:
DataValidationException – input data is not valid
SecureChannelException – operation not allowed
PukException – PUK code is not valid
- 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:
KeyGenerationException – There was an issue with generating the key
KeyAlreadyGenerated – The card already has a seed generated
- 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:
DerivationSelectionException – Card is not initialized with seed
ReadPublicKeyException – Invalid data received from card
- 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:
exceptions.SeedException – If no seed exists on the card
exceptions.ReadPublicKeyException – If invalid data received from card
- 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:
exceptions.DataValidationException – If p1 is invalid
exceptions.PukException – If PUK is incorrect
- 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:
exceptions.SeedException – If no seed/key loaded
exceptions.PinException – If PIN is incorrect
exceptions.DataValidationException – If data length is incorrect
exceptions.GenericException – If other errors occur
- 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:
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
KeyException – Seed not found
- 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:
- Raises:
DataValidationException – Nonce has to be 16 bytes
SeedException – There is no seed on the card
DataException – Data returned from the card is not valid
- 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:
PukException – PUK code not valid
CardNotBlocked – Card is not blocked, operation can’t be done
- 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:
PinException – Invalid PIN code
DataValidationException – Invalid length or PIN code authentication disabled
SoftLock – The card has been locked and needs power cycling before it can be used again
cryptnoxpy.card.basic_g1 module
Module containing class for Basic card of 1st generation
- class cryptnoxpy.card.basic_g1.BasicG1(*args, **kwargs)[source]
Bases:
BaseClass 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
- 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:
DataValidationException – input data is not valid
SecureChannelException – operation not allowed
PukException – PUK code is not valid
- 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:
KeyGenerationException – There was an issue with generating the key
KeyAlreadyGenerated – The card already has a seed generated
- 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:
DerivationSelectionException – Card is not initialized with seed
ReadPublicKeyException – Invalid data received from card
- 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:
exceptions.SeedException – If no seed exists on the card
exceptions.ReadPublicKeyException – If invalid data received from card
- 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:
exceptions.SeedException – If no seed/key loaded
exceptions.PinException – If PIN is incorrect
exceptions.DataValidationException – If data length is incorrect
exceptions.GenericException – If other errors occur
- 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
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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
- 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:
PinException – Invalid PIN code
DataValidationException – Invalid length or PIN code authentication disabled
SoftLock – The card has been locked and needs power cycling before it can be used again
- 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:
exceptions.DataValidationException – If p1 is invalid
exceptions.PukException – If PUK is incorrect
cryptnoxpy.card.custom_bits module
Module for making the uer data behave as a list
cryptnoxpy.card.nft module
Module containing class for NFT card
- class cryptnoxpy.card.nft.Nft(*args, **kwargs)[source]
Bases:
BasicG1Class containing functionality for NFT card which has limited capabilities
- type = 78
- 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:
DerivationSelectionException – Card is not initialized with seed
ReadPublicKeyException – Invalid data received from card
- 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:
exceptions.DataValidationException – If p1 is invalid
exceptions.PukException – If PUK is incorrect
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
- Raises:
DataValidationException – Nonce has to be 16 bytes
SeedException – There is no seed on the card
DataException – Data returned from the card is not valid
cryptnoxpy.card.user_data module
Module for making the uer data behave as a list
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:
objectObject 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:
DataValidationException – input data is not valid
SecureChannelException – operation not allowed
PukException – PUK code is not valid
- 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:
exceptions.SeedException – If no seed/key loaded
exceptions.PinException – If PIN is incorrect
exceptions.DataValidationException – If data length is incorrect
exceptions.GenericException – If other errors occur
- 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:
KeyGenerationException – There was an issue with generating the key
KeyAlreadyGenerated – The card already has a seed generated
- 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:
DerivationSelectionException – Card is not initialized with seed
ReadPublicKeyException – Invalid data received from card
- 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:
exceptions.SeedException – If no seed exists on the card
exceptions.ReadPublicKeyException – If invalid data received from card
- 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:
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
KeyException – Seed not found
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
exceptions.DataValidationException – If p1 is invalid
exceptions.PukException – If PUK is incorrect
- 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:
- Raises:
DataValidationException – Nonce has to be 16 bytes
SeedException – There is no seed on the card
DataException – Data returned from the card is not valid
- 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:
PukException – PUK code not valid
CardNotBlocked – Card is not blocked, operation can’t be done
- 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:
PinException – Invalid PIN code
DataValidationException – Invalid length or PIN code authentication disabled
SoftLock – The card has been locked and needs power cycling before it can be used again
- applet_version: List[int]
- serial_number: int
- class cryptnoxpy.card.BasicG1(*args, **kwargs)[source]
Bases:
BaseClass containing functionality for Basic cards of the 1st generation
- PUK_LENGTH = 12
- 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:
DataValidationException – input data is not valid
SecureChannelException – operation not allowed
PukException – PUK code is not valid
- 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:
exceptions.SeedException – If no seed/key loaded
exceptions.PinException – If PIN is incorrect
exceptions.DataValidationException – If data length is incorrect
exceptions.GenericException – If other errors occur
- 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:
KeyGenerationException – There was an issue with generating the key
KeyAlreadyGenerated – The card already has a seed generated
- 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:
DerivationSelectionException – Card is not initialized with seed
ReadPublicKeyException – Invalid data received from card
- 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:
exceptions.SeedException – If no seed exists on the card
exceptions.ReadPublicKeyException – If invalid data received from card
- 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
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
exceptions.DataValidationException – If p1 is invalid
exceptions.PukException – If PUK is incorrect
- 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
- 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:
PinException – Invalid PIN code
DataValidationException – Invalid length or PIN code authentication disabled
SoftLock – The card has been locked and needs power cycling before it can be used again
- applet_version: List[int]
- serial_number: int
- class cryptnoxpy.card.Nft(*args, **kwargs)[source]
Bases:
BasicG1Class containing functionality for NFT card which has limited capabilities
- 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:
DerivationSelectionException – Card is not initialized with seed
ReadPublicKeyException – Invalid data received from card
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
DataValidationException – input data is not valid
PukException – PUK code is not valid
- 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:
exceptions.DataValidationException – If p1 is invalid
exceptions.PukException – If PUK is incorrect
- 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:
- Raises:
DataValidationException – Nonce has to be 16 bytes
SeedException – There is no seed on the card
DataException – Data returned from the card is not valid
- 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
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.Basefor details.
- class cryptnoxpy.card.BasicG1[source]
Basic Generation 1 card implementation. See
cryptnoxpy.card.basic_g1.BasicG1for details.
- class cryptnoxpy.card.Nft[source]
NFT card implementation. See
cryptnoxpy.card.nft.Nftfor details.