If you have a blank JavaCard 3.0.5+ card (readily available for purchase on the web) you can build your own Keycard. There are two ways to get there:
cap files. This is the path to take if you just want Keycard running on a card of your own.Both paths need the same hardware:
Download the binary for your platform from the Keycard CLI releases page and rename it to keycard, dropping the platform suffix:
Every release carries a SHA256SUMS file covering all the binaries — check your download with sha256sum -c SHA256SUMS. On Linux you also need the PC/SC runtime (sudo apt install pcscd libpcsclite1); macOS and Windows need nothing else. The Linux binaries are built on Ubuntu 24.04, so they need glibc 2.39 or newer.
You need two files, both from the latest release of their repository:
| File | Download from | What it is |
|---|---|---|
keycard_vx.y.z.cap | status-keycard releases | The Keycard package, containing the Keycard, Ident, Cash and NDEF applets. |
math_jcop_vx.y.z.cap or math_soft_vx.y.z.cap | keycard-math-soft releases | The keycard-math library package (AID A0000008040002), which the Keycard package depends on since 4.0. |
Pick the math package that matches your card:
| Card | Math cap to load |
|---|---|
| JCOP | math_jcop_vx.y.z.cap |
| Anything else | math_soft_vx.y.z.cap |
The JCOP package only forwards the big number operations to the modular arithmetic NXP ships in the JCOP environment (com.nxp.id.jcopx.math), which is faster than doing it in JavaCard bytecode. The soft package is the portable software implementation, and is the one to take on any card that is not a JCOP.
With the card in the reader:
This loads the math package and installs the Keycard and Ident applets. --load-math is only needed the first time, since the library package stays on the card — leave it out on reinstallations. Use math_jcop_vx.y.z.cap instead if you are on a JCOP card.
The applet refuses every command — not even SELECT is answered — until it has an identity certificate, because the secure channel authenticates the card with that key. Load one:
--test generates a random identity and a certificate from the Keycard test CA, which is what you want while developing. A card with a test identity has to be explicitly trusted by the client: --test-card (or KEYCARD_TEST_CARD=true) with the CLI, the test CA as an anchor or a pinned card identity in the SDKs, the equivalent option in wallets.
If you are building a card you intend to use for real, generate the certificate under your own CA and load it with keycard load-ident --hex "0x..." instead, making sure the CA public key is the one your clients trust. Cards bought from us already carry a production identity and need none of this.
This sets up the PIN, PUK and (on applet versions before 4.0) the pairing password, generating them randomly and showing them once — pass --pin / --puk (or the KEYCARD_PIN / KEYCARD_PUK environment variables) to choose them yourself. Check everything worked with:
Done — your card is now a Keycard. Continue with the Keycard SDK or the Keycard API.
Building from source gives you the applet straight from the repository, plus a development environment you can iterate on. A single Gradle task builds the applet, installs it, and leaves the card initialized with a test identity.
Download and install OpenJDK 11 from Adoptium (select Windows, x64, JDK, .msi). You can either
set JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-11git clone --recurse-submodules https://github.com/keycard-tech/status-keycardcd status-keycard./gradlew testgradlew.bat testBUILD SUCCESSFUL you are done. The task loads both the keycard-math support package (required since 4.0) and the Keycard package, installs the Keycard, NDEF, Cash and Ident applets, then exercises them on the cardINIT with PIN 000000 and PUK 024680. So there is nothing else to do — the card answers commands right away, and clients just have to trust the test CA with --test-card / KEYCARD_TEST_CARD (or pin the card identity). Change the PIN with keycard change-pin if you keep using the card.If you do not want to run the tests, use ./gradlew install instead. It only loads the packages and installs the applets, leaving the card without an identity and uninitialized, so you then have to provision an identity and run keycard init as in the binary path above.
If you only want the cap file — for example to install the applet on a card you are not holding in a reader right now — run ./gradlew convertJavacard and find keycard.cap in the build directory.
After following the installation steps above your card will still be open to changes. This is very useful during development because you can repeat the installation steps as many times as you want to test changes you made to the app. To make your card immutable, in a way similar to what we do you need to do 2 things:
If you built from source, you can perform these two steps with ./gradlew lock from the status-keycard directory.
NOTE: THIS PROCEDURE IS NOT REVERSIBLE. THE AUTOMATED LOCKING TOOL DOES NOT PRINT OR STORE THE RANDOMLY GENERATED KEYS ANYWHERE