A GlobalPlatform card-management library for .NET — a C# port of Martin Paljak's GlobalPlatformPro (Java). It speaks the GlobalPlatform Card Specification to JavaCard-class smart cards: open SCP01/02/03 secure channels, load and install CAP files, rotate keys, and read the card registry — over any APDU transport you give it.
Card personalization increasingly happens inside card printers with built-in smart-card encoders — machines like the HID FARGO HDP6600 (and the DTC/HDP families in general), whose entire driver, SDK and application stack is .NET on Windows. When the host application that drives the printer, moves the card to the encoder and renders the artwork is a .NET service, the natural place for GlobalPlatform provisioning is the same process and the same runtime — not a bundled JVM and a subprocess.
This library was extracted from a production card-issuance station that provisions and prints
JavaCard smart cards on an HDP6600 in a single pass (dock to encoder → provision over PC/SC →
print → eject). It is transport-agnostic: anything that can shuttle APDU bytes (PC/SC via
winscard, a printer-SDK channel, a test transcript) can back it.
| Area | What you get |
|---|---|
| Secure channels | SCP01, SCP02, SCP03 (C-MAC, C-ENC, R-MAC, R-ENC modes) |
| Session | GpSession: SELECT, INITIALIZE UPDATE / EXTERNAL AUTHENTICATE, secure Transmit |
| CAP files | Parse and LOAD JavaCard CAP packages (CapFile, CapPackage), DAP signatures |
| Lifecycle | INSTALL [for load / install / make selectable], DELETE (with dependencies) |
| Keys | PUT KEY (rotate ISD keys), key diversification (EMV / VISA2 KDF templates), GpKeyInfo |
| Registry | GET STATUS parsing into GpRegistry / GpRegistryEntry (privileges, lifecycle states) |
| Card data | CPLC parsing, GET DATA helpers, delegated-management tokens and receipts |
| Plumbing | BER-TLV reader/writer, CommandApdu/ResponseApdu/StatusWord, EMV DGI records |
| Runtime | .NET 10, no native dependencies, IsAotCompatible, single MIT-licensed NuGet dependency |
using NexaTech.GlobalPlatform;
using NexaTech.GlobalPlatform.CapFiles;
using NexaTech.GlobalPlatform.Scp;
// Any APDU pipe works: PC/SC SCardTransmit, a printer-SDK channel, a mock…
var transmit = ApduTransmit.FromArrayTransmit(bytes => YourPcsc.Transmit(bytes));
// Attach to the Issuer Security Domain and open an SCP02/03 channel (auto-detected).
var session = new GpSession(transmit, new Aid("A000000003000000"));
session.Select(session.Aid);
session.OpenSecureChannel(
PlaintextKeys.DefaultKey(), // 40 41 42 … 4F test keys; or FromMasterKey(...)+Diversify(...)
scp: null, // null = detect from the card
hostChallenge: null, // null = random
ApduMode.Mac);
// Install an applet from a CAP file.
var cap = CapFile.FromFile("applet.cap");
session.LoadCapFile(cap, targetDomain: null, hashFunction: null);
session.InstallAndMakeSelectable(
cap.PackageAid, cap.AppletAids[0], instanceAid: null,
privileges: [], installParams: null);
// Inspect what's on the card.
var registry = session.GetStatus();The intended consumption model is source-level — pin a commit, build from source:
git submodule add https://github.com/nexatech-ltd/globalplatform-net externals/globalplatform-net<ProjectReference Include="externals/globalplatform-net/src/NexaTech.GlobalPlatform/NexaTech.GlobalPlatform.csproj" />This keeps the LGPL boundary obvious (the library stays a separate, replaceable assembly) and
needs no package feed. If you prefer a package, dotnet pack src/NexaTech.GlobalPlatform produces
a NuGet with the license and notices embedded — there is no public feed yet.
dotnet build NexaTech.GlobalPlatform.slnx -c Release
dotnet test tests/NexaTech.GlobalPlatform.TestsThe test suite includes transcript-replay tests: full SCP handshakes and secure-channel exchanges captured from real cards are verified byte-for-byte, so the crypto paths are exercised without hardware. CI runs on Linux and Windows — the library is pure managed code.
LGPL-3.0-only. Most of this library is a line-by-line C# translation of
GlobalPlatformPro (LGPL-3.0-or-later,
© Martin Paljak and contributors) and therefore a derivative work distributed under the same
terms. The Aid/CAP-file parsing portions derive from capfile
(MIT). APDU primitives, the BER-TLV codec and the SCP03 CMAC/KDF implementations are original
clean-room code contributed under the LGPL. Per-file provenance is recorded in each source
header; the full breakdown is in NOTICE.md.
Linking this library from a proprietary application is fine under LGPL §4–5 as long as it remains a replaceable assembly (keep it dynamically linked / JIT-compiled, or provide relinkable object files). See the compliance note in NOTICE.md.
This project exists because GlobalPlatformPro documented, in working code, a protocol that is otherwise painful to get right. Thank you, Martin Paljak.