← Back to the tool

Public-key · Under the hood

A PKCS#11 session, using real keys

What each button in the tool actually computes, step by step — with the real formulas.

The browser as a stand-in token

There's no way for a web page to reach a real HSM or smart card driver, so this tool doesn't try to simulate one. Instead, it runs a real ECDSA key pair through the browser's own Web Crypto API, narrated with the exact Cryptoki function names a real token-backed application would call in the same order — C_OpenSession, C_GenerateKeyPair, C_Sign, and so on. Every cryptographic operation you see is genuine; only the "hardware" is a stand-in.

extractable is CKA_EXTRACTABLE

Clicking "Generate key pair" calls crypto.subtle.generateKey with the private key's extractable flag set to false — the browser's direct equivalent of a token creating an object with CKA_EXTRACTABLE = false. This isn't cosmetic: the browser itself will now refuse any attempt to export or wrap that specific key handle, for the rest of the page's life. Nothing in this tool's own code enforces that refusal — the underlying platform does, exactly like a real token's firmware would.

C_Sign works; C_WrapKey doesn't

Signing (C_SignInit + C_Sign in Cryptoki terms) works normally — using a non-extractable key for its intended operation is exactly what CKA_EXTRACTABLE = false is meant to allow. But clicking "Attempt C_WrapKey" calls crypto.subtle.wrapKey on that same private key handle, which throws — a real InvalidAccessError, not a message this tool invented. That's the identical refusal (CKR_KEY_UNEXTRACTABLE) a correctly configured token gives when an application asks it to do something CKA_EXTRACTABLE was specifically set to prevent.

What CKA_EXTRACTABLE = false allows

  • •Sign, verify, encrypt, decrypt — using the key, as many times as needed
  • •Generating new key pairs, indefinitely

What it blocks — no exceptions

  • •Exporting the raw key value, in any format
  • •Wrapping the key under another key — wrapping is still a form of export

The correct way to move a key off the token

The last section generates a separate, ordinary AES data key with extractable: true — the equivalent of a session key that's meant to be exported — and wraps that one successfully with AES-KW, the same mechanism used in the key-wrapping use case. This is the actual PKCS#11 pattern for moving key material: never make a long-lived private signing key extractable; generate short-lived, extractable session keys instead, and wrap only those.

Now try it

Back to A PKCS#11 session, using real keys →

Walk through an actual Cryptoki call sequence — login, generate a key pair, sign, and attempt to wrap a non-extractable private key — with real Web Crypto operations standing in for the hardware token.