Skip to main content

Non-Exportable Keys

Your PQC private keys are the most sensitive assets in Qpher. A leaked private key would allow an attacker to decrypt your ciphertexts or forge signatures in your name. That is why Qpher follows one rule: private keys are generated and used only inside the isolated key service (KMS-Orchestrator), and are never exported.

Security

There is no API endpoint to retrieve private keys — by design.

How It Works​

When you generate a PQC key pair through Qpher, the following happens:

  1. Key generation occurs inside the KMS-Orchestrator service.
  2. The public key is returned to you and stored in the database. You can retrieve it at any time.
  3. The private key is encrypted by a key held in Google Cloud KMS and stored as an envelope file in the KMS-Orchestrator's key store.
  4. The database stores only a handle (a file path reference), never the raw key bytes.
You receive: Stored by the KMS-Orchestrator:
+--------------------------+ +----------------------------------+
| Public Key | | Private key, encrypted by a |
| (1184 bytes | | Google Cloud KMS key |
| for Kyber768) | | -> {version}.key.envelope |
+--------------------------+ +----------------------------------+
|
Database stores only:
"handle" = {tenant}/{algorithm}/{version}

No Export API​

Qpher intentionally provides no endpoint for downloading or exporting private keys. This is not a missing feature -- it is a deliberate security decision.

OperationAvailable?How It Works
Generate key pairYesPrivate key created and stored inside KMS-Orchestrator
Get public keyYesPublic key returned from the database
Get private keyNoNo such endpoint exists
Export private keyNoNo such endpoint exists
Encrypt / DecryptYesKMS-Orchestrator performs the operation using the private key internally
Sign / VerifyYesKMS-Orchestrator performs the operation using the private key internally

Server-Side Cryptographic Operations​

Since you cannot download private keys, all cryptographic operations that require a private key happen inside Qpher:

  • Decrypt: You send the ciphertext to Qpher. The KMS-Orchestrator loads the private key, performs Kyber768 decapsulation, and returns the plaintext.
  • Sign: You send the message to Qpher. The KMS-Orchestrator loads the private key, performs Dilithium3 signing, and returns the signature.

Operations that use only the public key (encrypt, verify) can also be performed client-side if you prefer, since public keys are freely available.

Client-Side Verification

You can verify signatures locally using the public key and any ML-DSA-65 (FIPS 204) implementation. This is useful when you want to verify data integrity without making an API call.

Private Key Storage Details​

In production:

  • Encryption: each private key is encrypted by a key held in Google Cloud KMS (authenticated encryption); an envelope cannot be read without a Cloud KMS Decrypt call.

For more details on the encryption scheme, see Encryption at Rest.

Key Lifecycle Respect​

The non-exportable rule applies across the entire key lifecycle:

Key StatusCan Load Private Key?Allowed Operations
ActiveYes (internally only)Encrypt, decrypt, sign, verify
RetiredYes (internally only)Decrypt, verify only
ArchivedNoNo operations allowed

Even when a key is active, only the KMS-Orchestrator's code loads it.

Why This Matters​

Why it is built this way:

  • One place loads keys: only the KMS-Orchestrator's code loads private keys.
  • No accidental exposure: private keys are never written to logs, error messages, API responses or the database — the database holds only a handle.
  • Auditability: each private-key operation writes an audit event.