Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Usage example

miltolstoy edited this page Sep 8, 2025 · 1 revision

SCP03 implementation guide

Below is step-by-step explanation of how to use SCP03 protocol to communicate with a smart card. The similar approach can be used for SCP11. Also please refer to SCP Reader class example at examples/scp03_reader_template.py file

Define SCP03 keys

Declare static SCP03 keys:

enc_key = bytes.fromhex("...")
mac_key = bytes.fromhex("...")
dek_key = bytes.fromhex("...")

Declare reference to these keys on the smart card:

key_id = 0x01
key_version = 0x30

Define connection class to smart card

Implement SmartCardConnection interface using your connection to the smart card:

class MySmartCardConnection(SmartCardConnection):
    def send_and_receive(self, apdu: bytes) -> bytes:
        # Use your physical channel to the smart card
        return rapdu

    def is_extended_length_apdu_supported(self) -> bool:
        # Return your smart card property
        return True

    def close_connection(self) -> None:
        # Close your physical chanel to the smart card
        pass

See the SmartCardConnection docstrings for additional information.

Create and use SCP03 session

Set SCP03 mode (S8 or S16) and initialize SCP03 protocol using variables declared above:

session = SecurityDomainSession(MySmartCardConnection())
session.authenticate_scp03(key_id, key_version, enc_key, mac_key, dek_key, ScpMode.S8)

Transmit APDUs:

# GlobalPlatform Card Specification, "11.4 GET STATUS Command"
get_status_capdu = Apdu(
    0x80, # CLA
    0xF2, # INS
    0x40, # P1 - list applets or security domains
    0x00, # P2
    bytes.fromhex("4F00")) # data - search qualifier: all IDs
rapdu_data = session.send_and_receive(get_status_capdu)

SCP11 implementation guide

Below is step-by-step explanation of how to use SCP11 protocol to communicate with a smart card. Also please refer to SCP Reader class example at examples/scp11_reader_template.py file

Define SCP11 credentials

Declare OCE SCP11 certificates chain and private key:

cert_chain_oce_ecka_p256 = [bytes.fromhex("..."), ...]
sk_oce_ecka_p256 = bytes.fromhex("...")

Declare AES algorithm for session keys that will be generated:

aesAlg = AesAlg.AES_256

Declare reference to SD and OCE keys on the smart card:

session_key_id = 0x11
session_key_version = 0x03

oce_key_id = 0x10
oce_key_version = 0x03

Define connection class with SCP11 to smart card

Please see the corresponding section in the SCP03 guide above

Create and use SCP11 session

Get SD certificate public key from the smart card:

session = SecurityDomainSession(MySmartCardConnection())
certificates = session.get_certificate_bundle(session_key_id, session_key_version)
cert_sd_ecka = certificates[-1]
pk_sd_ecka = cert_sd_ecka.get_public_key()

Set SCP03 mode (S8 or S16) for session keys and initialize SCP11 protocol using variables declared above:

session.authenticate_scp11(session_key_id,
                            session_key_version,
                            oce_key_id,
                            oce_key_version,
                            pk_sd_ecka,
                            cert_chain_oce_ecka_p256
                            sk_oce_ecka_p256,
                            aesAlg,
                            ScpMode.S8)

See APDU transmission example in the corresponding section of the SCP03 guide above.