KeyCard.py documentation

Add your content using reStructuredText syntax. See the reStructuredText documentation for details.

class keycard.keycard.KeyCard(transport=None, ca_public_keys=None, trusted_identity_keys=None)

High-level interface for interacting with a Keycard device.

This class provides convenient methods to manage pairing, secure channels, and card operations.

change_pairing_secret(new_value)

Changes the pairing secret on the card.

Return type:

None

Parameters:

new_value (str) – The new pairing secret value to set.

Raises:
  • ValueError – If input format is invalid.

  • APDUError – If the response status word is not 0x9000.

change_pin(new_value)

Changes the user PIN on the card.

Return type:

None

Parameters:

new_value (str) – The new PIN value to set.

Raises:
  • ValueError – If input format is invalid.

  • APDUError – If the response status word is not 0x9000.

change_puk(new_value)

Changes the PUK on the card.

Return type:

None

Parameters:

new_value (str) – The new PUK value to set.

Raises:
  • ValueError – If input format is invalid.

  • APDUError – If the response status word is not 0x9000.

derive_key(path='')

Set the derivation path for subsequent SIGN and EXPORT KEY commands.

Return type:

None

Parameters:

path (str) – BIP-32-style path (e.g., “m/44’/60’/0’/0/0”) or “../0/1” (parent) or “./0” (current).

ecdh(public_key, path)

Compute an ECDH shared secret with the key at a path. Needs applet 4.0. The result is a raw secret; apply the protocol’s KDF to it.

Return type:

bytes

Parameters:
  • public_key (bytes) – The peer’s uncompressed public key, 65 bytes.

  • path (str) – Path under “m/44’/1237’” (NIP-44) or “m/43’/60’/1581’” (EIP-1581), at least 5 levels deep.

Returns:

The 32-byte X coordinate of the shared point.

Return type:

bytes

export_bip85(path, length)

Export BIP-85 entropy derived from the loaded key. Needs applet 4.0.

Return type:

bytes

Parameters:
  • path (str) – Path starting with “m/83696968’”, every component hardened, e.g. “m/83696968’/0’/0’”.

  • length (int) – Number of entropy bytes, 1 to 64.

Returns:

The entropy.

Return type:

bytes

export_current_key(public_only=False)

Exports the current key from the card.

This is a convenience method that uses the CURRENT derivation option and does not require a keypath.

Return type:

ExportedKey

Parameters:

public_only (bool) – If True, only the public key will be returned.

Returns:

An object containing the public key, and optionally

the private key and chain code.

Return type:

ExportedKey

export_key(derivation_option, public_only, keypath=None, make_current=False, source=DerivationSource.MASTER)

Export a key from the card.

This is a proxy for keycard.commands.export_key(), provided here for convenience.

Return type:

ExportedKey

Parameters:
  • derivation_option – One of the derivation options (CURRENT, DERIVE, DERIVE_AND_MAKE_CURRENT).

  • public_only – If True, only the public key will be returned.

  • keypath – BIP32-style string (e.g. “m/44’/60’/0’/0/0”) or packed bytes. If derivation_option is CURRENT, this can be omitted.

  • make_current – If True, updates the card’s current derivation path.

  • source – Which node to derive from: MASTER, PARENT, or CURRENT.

Returns:

An object containing the public key, and optionally

the private key and chain code.

Return type:

ExportedKey

See also

export_lee(path='m')

Export the LEE keys at a path. Needs applet 4.0 in LEE mode.

Return type:

LeeKeys

Parameters:

path (str) – Derivation path from the master key, e.g. “m/44’/60’”. Defaults to the master keys.

Returns:

ASK, NSK, VSK_D and VSK_Z.

Return type:

LeeKeys

factory_reset()

Sends the FACTORY_RESET command to the card.

The card closes any secure channel and forgets its credentials, so the session, PIN and initialization state are reset.

Return type:

None

Raises:

APDUError – If the card returns a failure status word.

generate_key()

Generates a new key on the card and returns the key UID.

Return type:

bytes

Returns:

Key UID (SHA-256 of the public key)

Return type:

bytes

Raises:

APDUError – If the response status word is not 0x9000

generate_mnemonic(checksum_size=6)

Generate a BIP39 mnemonic using the card’s RNG.

Return type:

list[int]

Parameters:

checksum_size (int) – Number of checksum bits (between 4 and 8 inclusive).

Returns:

List of integers (0-2047) corresponding to wordlist

indexes.

Return type:

List[int]

get_challenge(length)

Gets random bytes generated by the card.

Applet 4.0 needs an open secure channel, but not an initialized card. Earlier applets that support the command also answer without a channel.

Return type:

bytes

Parameters:

length (int) – Number of bytes, 1 to 255; the card limits it to 245 over Secure Channel V2 and 221 over V1.

Returns:

The random bytes.

Return type:

bytes

Raises:
  • ValueError – If the length does not fit in P1.

  • InvalidStateError – If a 4.x card has no open secure channel.

get_data(slot=StorageSlot.PUBLIC)

Gets the data on the card previously stored with the store data command in the specified slot.

NDEF data is the complete NDEF file, starting with its 2-byte length. Applets before 4.0 return at most the first 223 bytes.

Return type:

bytes

Parameters:

slot (StorageSlot) – Where to retrieve the data (PUBLIC, NDEF, CASH)

Raises:

InvalidResponseError – If segmented NDEF data is malformed.

property get_key_path: dict[str, int | bool] | list[int]

Returns the current key derivation path from the card.

Returns:

List of 32-bit integers representing the key path.

Return type:

list of int

Raises:

RuntimeError – If the secure session is not open.

ident(challenge=None)

Sends an identity challenge to the card.

Return type:

bytes

Parameters:

challenge (bytes) – A challenge (nonce or data) to send to the card. If None, a random 32-byte challenge is generated.

Returns:

The public key extracted from the card’s identity response.

Return type:

bytes

property identity_certificate: bytes | None

The card’s Identity Certificate from SELECT (4.x only).

Returns:

The 98-byte certificate, or None.

Return type:

bytes

init(pin, puk, pairing_secret=None, pin_retries=None, puk_retries=None, alt_pin=None)

Initializes the card with its credentials.

Secure Channel V1 cards need the pairing secret. Secure Channel V2 cards take none; the channel is opened if needed and stays open.

Return type:

None

Parameters:
  • pin (str) – The 6-digit PIN.

  • puk (str) – The 12-digit PUK.

  • pairing_secret – The pairing secret (Secure Channel V1 only).

  • pin_retries (int) – PIN attempts, 2 to 10 (default 3).

  • puk_retries (int) – PUK attempts, 3 to 12 (default 5).

  • alt_pin (str) – Optional 6-digit Alternate PIN.

Raises:

ValueError – If the pairing secret is missing on V1, given on V2, or a parameter is out of range.

property is_initialized: bool

Checks if the Keycard is initialized.

Returns:

True if the Keycard is initialized, False otherwise.

Return type:

bool

property is_pin_verified: bool

Checks if the user PIN has been verified.

Returns:

True if the PIN is verified, False otherwise.

Return type:

bool

property is_secure_channel_open: bool

Checks if a secure channel is currently open.

Returns:

True if a secure channel is established, False otherwise.

Return type:

bool

property is_selected: bool

Checks if the Keycard applet has been selected.

Returns:

True if a card is selected, False otherwise.

Return type:

bool

property is_session_open: bool

Checks if a secure session is currently open.

Returns:

True if a secure session is established, False otherwise.

Return type:

bool

load_key(key_type, public_key=None, private_key=None, chain_code=None, bip39_seed=None)

Load a key into the card for signing purposes.

Return type:

bytes

Parameters:
  • key_type – Key type

  • public_key – Optional ECC public key (tag 0x80).

  • private_key – ECC private key (tag 0x81).

  • chain_code – Optional chain code (tag 0x82, only for extended key).

  • bip39_seed – 16 to 64-byte binary seed (only for key_type BIP39_SEED, or LEE_SEED to also derive the LEE keys on applet 4.0).

Returns:

UID of the loaded key (SHA-256 of public key).

mutually_authenticate()

Performs mutual authentication between host and card.

Return type:

None

Raises:
open_secure_channel()

Opens a secure session with the card.

Secure Channel V1 cards use pairing (set by pair() or assigned) and run MUTUALLY AUTHENTICATE. Secure Channel V2 cards need an Identity Certificate signed by one of ca_public_keys, or an Identity Key in trusted_identity_keys.

Return type:

None

Raises:
pair(shared_secret, pairing_mode=PairingMode.ANY)

Pairs with the card using an ECDH-derived shared secret.

Return type:

Pairing

Parameters:

shared_secret (bytes) – 32-byte ECDH shared secret.

The pairing is stored in pairing for open_secure_channel.

Returns:

The pairing slot and key.

Return type:

Pairing

Raises:

InvalidStateError – If the card does not use Secure Channel V1.

remove_key()

Removes the current key from the card.

Return type:

None

Raises:

APDUError – If the response status word is not 0x9000.

property secure_channel_version: SecureChannelVersion | None

The secure channel version the selected card uses.

Returns:

V2 from applet 4.0, V1 before, or None

before select().

Return type:

SecureChannelVersion

select()

Selects the Keycard applet and retrieves application metadata.

Selecting the applet closes any secure channel on the card, so the session and PIN state are reset.

Return type:

ApplicationInfo

Returns:

The card’s application information.

Return type:

ApplicationInfo

send_raw_apdu(apdu)

Sends a complete APDU and returns the raw response.

Return type:

APDUResponse

Returns:

The response data and status word.

Return type:

APDUResponse

set_pinless_path(path)

Set a PIN-less path on the card. Allows signing without PIN/auth if the current derived key matches this path.

Return type:

None

Parameters:

path (str) – BIP-32-style path (e.g., “m/44’/60’/0’/0/0”). An empty string disables the pinless path.

sign(digest, algorithm=SigningAlgorithm.ECDSA_SECP256K1, tweak=None)

Sign using the currently loaded keypair; on applet 4.0, which has no current key, the master key. Requires PIN verification and secure channel.

Return type:

SignatureResult

Parameters:
  • digest (bytes) – 32-byte hash to sign

  • algorithm (SigningAlgorithm) – ECDSA_SECP256K1 (default) or, on applet 4.0, SCHNORR_BIP340.

  • tweak (Optional[bytes]) – 32-byte Schnorr tweak; zeros if omitted.

Returns:

Parsed signature result, including the signature

(DER or raw), algorithm, and optional recovery ID or public key.

Return type:

SignatureResult

sign_pinless(digest)

Sign using the predefined PIN-less path. Does not require secure channel or PIN.

Return type:

SignatureResult

Parameters:

digest (bytes) – 32-byte hash to sign

Returns:

Parsed signature result, including the signature

(DER or raw), algorithm, and optional recovery ID or public key.

Return type:

SignatureResult

Raises:

APDUError – if no PIN-less path is set

sign_with_path(digest, path, make_current=False, algorithm=SigningAlgorithm.ECDSA_SECP256K1, tweak=None)

Sign using a derived keypath. Optionally updates the current path.

Return type:

SignatureResult

Parameters:
  • digest (bytes) – 32-byte hash to sign

  • path (str) – BIP-32-style path (e.g. “m/44’/60’/0’/0/0”); “m” is the master key

  • make_current (bool) – whether to update current path on card (not supported by applet 4.0)

  • algorithm (SigningAlgorithm) – ECDSA_SECP256K1 (default) or, on applet 4.0, SCHNORR_BIP340.

  • tweak (Optional[bytes]) – 32-byte Schnorr tweak; zeros if omitted.

Returns:

Parsed signature result, including the signature

(DER or raw), algorithm, and optional recovery ID or public key.

Return type:

SignatureResult

property status: dict[str, int | bool] | list[int]

Retrieves the application status using the secure session.

Returns:

A dictionary with:
  • pin_retry_count (int)

  • puk_retry_count (int)

  • initialized (bool)

Return type:

dict

Raises:

RuntimeError – If the secure session is not open.

store_data(data, slot=StorageSlot.PUBLIC)

Stores data on the card in the specified slot.

NDEF data is the complete NDEF file, starting with its 2-byte length.

Return type:

None

Parameters:
  • data (bytes) – The data to store (max 127 bytes, or 512 bytes for NDEF from applet 3.2).

  • slot (StorageSlot) – Where to store the data (PUBLIC, NDEF, CASH)

Raises:

ValueError – If the data is too long.

unblock_pin(puk, new_pin)

Unblocks the user PIN using the provided PUK and sets a new PIN.

Return type:

None

Parameters:

puk_and_pin (str | bytes) – Concatenation of PUK (12 digits) + new PIN (6 digits)

Raises:
  • ValueError – If the format is invalid.

  • APDUError – If the card returns an error.

unpair(index)

Removes a pairing slot from the card.

Return type:

None

Parameters:

index (int) – Index of the pairing slot to remove.

Raises:

InvalidStateError – If the card does not use Secure Channel V1.

verify_pin(pin)

Verifies the user PIN with the card.

Return type:

bool

Parameters:

pin (str) – The user-entered PIN.

A failed attempt also clears a previous verification, as it does on the card.

Returns:

True if PIN is valid, otherwise False.

Return type:

bool

property version: tuple[int, int]

Retuns tuple with major and minor version number

Returns:

[major_version, minor_version]

Return type:

[int, int]