Skip to content

Usage example

miltolstoy edited this page Jul 23, 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/Scp03ReaderTemplate.java file

Define SCP03 keys

Declare static SCP03 keys:

byte[] encKey = {...};
byte[] macKey = {...};
byte[] dekKey = {...};
StaticKeys staticKeys = new StaticKeys(encKey, macKey, dekKey);

Declare reference to these keys on the smart card:

byte keyId = (byte) 0x01;
byte keyVersionNumber = (byte) 0x30;
KeyRef keyRef = new KeyRef(keyId, keyVersionNumber);

Declare SCP03 key parameters from these values:

Scp03KeyParams keyParams = new Scp03KeyParams(keyRef, staticKeys);

Define connection class to smart card

Implement SmartCardConnection interface using your connection to the smart card:

class MySmartCardConnection implements SmartCardConnection {
    @Override
    public byte[] sendAndReceive(byte[] apdu) {
        // Use your physical channel to the smart card
        return rapdu;
    }

    @Override
    public boolean isExtendedLengthApduSupported() {
        // Return your smart card property
        return true;
    }

    @Override
    public void close() {
        // Close your physical chanel to the smart card
    }
}

See the SmartCardConnection JavaDocs for additional information.

Create and use SCP03 session

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

SecurityDomainSession session = new SecurityDomainSession(new MySmartCardConnection());
session.authenticate(keyParams, ScpMode.S8);

Transmit APDUs:

// GlobalPlatform Card Specification, "11.4 GET STATUS Command"
Apdu getStatusCapdu = new Apdu(
    (byte) 0x80,  // CLA
    (byte) 0xF2,  // INS
    (byte) 0x40,  // P1 - list applets or security domains
    (byte) 0x00,  // P2
    new byte[] {(byte) 0x4F, (byte) 0x00)});  // data - search qualifier: all IDs
byte[] rapduData = session.sendAndReceive(getStatusCapdu);

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/Scp11ReaderTemplate.java file

Define SCP11 credentials

Declare OCE SCP11 encoded certificates chain and private key

List<byte[]> certChainOceEcka = ...;
PrivateKey skOceEcka = ...;

Declare AES algorithm for session keys that will be generated:

AesAlg sessionKeysAlg = AesAlg.AES_256;

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

byte sessionKeyId = (byte) 0x11;
byte sessionKeyVersionNumber = (byte) 0x03;
KeyRef sessionKeyRef = new KeyRef(keyId, sessionKeyVersionNumber);

byte oceKeyId = (byte) 0x10;
KeyRef oceKeyRef = new KeyRef(oceKeyId, sessionKeyRef.getKvn());

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's public key from the smart card:

SecurityDomainSession session = new SecurityDomainSession(new MySmartCardConnection());
List<ScpCertificate> sdCertChain = session.getCertificateBundle(sessionKeyRef);
int eckaCertPosition = sdCertChain.size() - 1;
PublicKey pkSdEcka = sdCertChain.get(eckaCertPosition).getPublicKey();

Declare SCP11 key parameters from these values:

Scp11KeyParams keyParams = 
  new Scp11KeyParams(sessionKeyRef, pkSdEcka, oceKeyRef, skOceEcka, certChainOceEcka, sessionKeysAlg);

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

session.authenticate(keyParams, ScpMode.S8);

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