Back to Products

PKCS Smart Card Systems

A PKCS#11 middleware and client platform that makes physical smart cards usable from ordinary enterprise applications — hardware-backed authentication, digital signing and certificate management.

Built on MicroFrame Government & Security
PKCS#11 .NET PKI Smart Card Digital Signature

The problem

Where a signature has to rest on a hardware-held key — and hardware is exactly where application developers stop. PKCS#11 readers, drivers and card form factors differ per vendor, and bridging them into a business application, a browser flow or an existing PKI is specialist work that most product teams are not equipped to take on.

Our approach

We built the bridge once, as middleware with an open integration surface. Applications call a stable interface for signing, certificate and verification operations; the middleware absorbs the differences between readers and card vendors and speaks to existing IAM and PKI infrastructure — so hardware-backed identity becomes something an application can adopt rather than something it has to specialise in.

What the platform does

The platform provides smart card-based authentication and digital signature capability built on the PKCS#11 standard, integrating physical smart card hardware with the software layer to give high-security enterprise and government applications hardware-backed identity.

It covers digital signing, certificate management, encrypted communication and secure document verification. Its architecture is deliberately open for integration with existing enterprise applications and IAM/PKI systems, and it is built for signing flows in e-Government, fintech and legal document processes. Whether a signature is legally valid depends on the certificate and the certificate service provider used, not on the middleware alone.

Capabilities

  • PKCS#11 interface for hardware-based cryptographic operations
  • Digital document signing with the key kept on the card
  • Certificate management — issuance, renewal and revocation workflows
  • Encrypted communication for secure exchange between parties
  • Secure document verification with tamper-evident validation
  • IAM/PKI integration with existing identity infrastructure
  • Multi-vendor card reader support across hardware form factors
  • Built for e-Government and fintech flows where signing is regulated

How it is built

  • .NET middleware bridging PKCS#11 hardware and the application layer
  • Support for multiple smart card reader vendors and form factors
  • Certificate chain validation with OCSP/CRL checking
  • Cross-platform desktop client with browser extension support

What the middleware exists to hide

PKCS#11 is a standard, which misleads people into expecting uniformity. What actually differs between vendors is nearly everything an application would have to handle:

  • Where the module is and what it is called. The library name and install path differ per vendor and per operating system, so discovery cannot be a constant.
  • Slot and token semantics. “Reader connected”, “card inserted” and “token initialized” are three distinct conditions that modules report differently, and a card can be removed between two calls that an application thinks of as one operation.
  • Which mechanisms a card actually implements. Whether hashing happens on the card or on the host, which padding schemes are supported, and which key sizes and algorithms a particular card will accept vary by card, not just by vendor. An application that assumes one mechanism works everywhere works with one card.
  • PIN handling. Some readers take the PIN from the host, some have a pinpad and take it directly with the host never seeing it. Those are different flows and cannot be papered over with the same function call.
  • Concurrency. Not every module is thread-safe, and sessions carry login state, so access to a token has to be serialized whether or not the application knows that.
  • Error reporting. This is where the real damage is. A wrong PIN, a locked card, a removed card and a genuinely failed operation are not consistently distinguishable across modules, and an application that treats them as one class and retries will decrement the PIN retry counter and lock the user’s card.

The middleware normalizes all of it into a small, explicit set of outcomes, and treats anything that could consume a PIN attempt as non-retryable by policy rather than leaving that judgement to the caller. That single rule is the difference between a support queue full of locked cards and one that is not.

The key never leaves, and that dictates the API shape

A hardware-held private key is non-extractable by design, so there is no “fetch the key and sign locally” path — every signature is a round trip to a card that is slow relative to software cryptography and can be physically removed mid-operation. The API is therefore asynchronous and cancellable, and hashing is done on the host wherever the card supports signing a pre-computed digest, so what crosses the reader interface is a digest rather than a document. A long document is never streamed to a card, and a signature is not a function that blocks a UI thread for an unpredictable interval.

Signing a document is not the same as signing bytes

A legally meaningful signature is over a defined structure — what was signed, with which certificate, and the signed attributes that go with it — not over a raw file. The middleware builds that structure on the host and asks the card only for the raw cryptographic operation over the resulting digest. Keeping the format on the host side means the differences between cards cannot change what a signature actually covers, and the signature format can be adapted without touching the hardware layer.

Revocation is a freshness problem, so both mechanisms are used

Chain validation is the easy half. The hard half is that revocation is time-dependent and the two ways of checking it have opposite weaknesses: OCSP gives a fresh answer but adds a live network dependency on a responder that can be slow or unavailable, while a CRL works without one but is only as current as its issue window. The client does both — OCSP with CRL fallback — because either alone fails in a way the other covers.

The validation result is recorded along with the evidence it was based on. A verification that cannot be reproduced later is not a verification, and this matters most in the case that actually arises: a signature made while a certificate was valid must still verify after that certificate has expired, which means validation is always anchored to a point in time rather than asked in the present tense.

The browser flow, and the trust decision inside it

Page script cannot talk to a PKCS#11 module, and no amount of wanting it to changes that. So the browser path is a page requesting a signature, an extension relaying the request, and a locally running native component that owns the module and the reader. That indirection forces a decision that is easy to skip: the local component has to authenticate the origin making the request and show the user what is about to be signed. Without both, any page open in the browser can ask a card sitting in a reader to sign something the user never saw — the card cannot tell the difference, so the host has to.

Reader and driver stacks differ per operating system even where the underlying smart card interface is common, so module loading and device access are isolated behind one internal interface and the rest of the desktop client is the same code on every platform. Card-based authentication is handed to the identity layer as a completed proof rather than running as a parallel login, so a card session and a password session end up in the same session model with the same lifetime rules.

Ready to Start?

Ready to start your project?

Let's discuss how we can help bring your ideas to life.