Communication with the card happens over a Secure Channel. Since applet 4.0 the channel is authenticated by a certificate the card is programmed with at the factory, so there is nothing to pair and nothing to persist. The SDK picks the protocol version automatically from the applet version reported at selection, so the same code works with 4.0 and 3.x cards.
The card proves its identity with a 98-byte certificate returned in the SELECT response. The SDK verifies it during the handshake and throws if it does not check out — you do not call anything explicitly, you only have to tell the SDK which certification authorities you trust.
The default constructor trusts the Keycard production CA, which is the right choice for almost every integration. Pass your own anchors when you also need to accept test cards:
| CA | Compressed secp256k1 public key (33 bytes, hex) |
|---|---|
| Keycard production | 029a9b9ee1e7a71bdf45b3f9c58c99866ff1294d2c1e304e228a86e10c3343501c |
| Keycard test cards | 025877220aaae6e54a6f974602d5995c0fe24a3ea7ddabd8644bec795b9da00743 |
A card built by yourself carries no certificate, or one from a CA you did not add. Rather than adding its CA you can pin the card identity directly, which is usually what you want in a lab:
Once a card has been accepted, the SDK pins its identity for the rest of the session, so a substituted card mid-session is rejected.
A session must be opened every time the applet is selected — including after the card leaves the field, since the card forgets the session when it is deselected. After that the SDK handles the channel transparently, encrypting commands and decrypting responses.
That is the whole call. There is no pairing step before it and no return value to store.
Earlier versions required each client to pair with each card and keep the resulting pairing secret. That is gone on 4.0: no autoPair, no setPairing, no pairing password, and nothing to write to secure storage. Code that still carries a pairing record for a 4.0 card can delete it.
autoPair only when
cmdSet.getApplicationInfo().getAppVersion() < 0x0400. The underlying
differences are described in
Secure Channel v1 (legacy).