Skip to content

Authentication Model

This page provides a detailed technical explanation of BlokSec’s authentication model for security teams evaluating the platform.

BlokSec’s core security property is that no single party can forge an authentication. The user’s private key is encrypted and the decryption requires three independent factors:

FactorWhere it livesWho controls it
Encrypted key envelope + server saltBlokSec databaseBlokSec infrastructure
Device saltQR code / mobile devicePhysical possession
PIN or passphraseUser’s memoryUser knowledge

An attacker would need to compromise all three simultaneously to forge an authentication.

When a user enrolls (or when a BlokBadge is issued), BlokSec generates:

  1. An Ed25519 key pair using the Web Crypto API with true cryptographic randomness
  2. A server salt — 16 random bytes, stored in the database
  3. A device salt — 16 random bytes, encoded in Base62, embedded in the QR code
  4. A random IV — 12 bytes for AES-GCM encryption

The private key is immediately encrypted and never stored in plaintext.

The private key is encrypted using AES-256-GCM with a key-encryption-key (KEK) derived through a dual-salt process:

Step 1: intermediate = PBKDF2-SHA256(PIN, serverSalt, 100000 iterations)
Step 2: KEK = HKDF-SHA256(intermediate, deviceSalt, "bloksec-badge-v1")
Step 3: encryptedKey = AES-256-GCM(privateKey, KEK, IV, AAD)

The Additional Authenticated Data (AAD) binds the encrypted key to its context:

AAD = "{clientShortCode}:{userShortCode}:{timestamp}"

This prevents an attacker from swapping encrypted key envelopes between users. Decryption will fail if the AAD doesn’t match.

The badge/credential record in the database contains:

FieldDescription
envelope.encryptedKeyAES-256-GCM ciphertext (IV + encrypted private key)
envelope.serverSalt16-byte random salt for PBKDF2
envelope.publicKeyEd25519 public key (SPKI format) for signature verification
envelope.timestampWhen the envelope was created (part of AAD)
deviceSaltHashSHA-256 hash of the device salt — used to verify the correct device salt is presented, without storing the actual salt

The server does not store:

  • The device salt (only its hash)
  • The user’s PIN
  • The decrypted private key

When a user authenticates:

  1. The device salt arrives from the QR code scan (or from the mobile device for push-based auth)
  2. The server verifies SHA-256(deviceSalt) == storedDeviceSaltHash
  3. The user provides their PIN
  4. The server derives the KEK using PBKDF2 + HKDF
  5. The server decrypts the private key using AES-256-GCM with the KEK and AAD
  6. The server creates a digital signature over the authentication data using the decrypted Ed25519 private key
  7. The private key is immediately discarded from memory
  8. The server verifies the signature using the stored public key

If any step fails (wrong device salt, wrong PIN, tampered AAD), decryption fails and the authentication is rejected.

BlokSec supports configurable security levels per credential:

LevelFormatStrengthUse case
0None (server-managed)LowestKiosk, shared terminal
14-digit PINLowFamiliar but weak
26-digit PINModerateDefault for most deployments
38-character alphanumericHighSensitive applications
412+ character passphraseHighestCritical infrastructure

Level 0 uses a server-managed passphrase that is encrypted with a per-client key and stored alongside the badge. This removes the user knowledge factor but retains the device factor and server factor.

A new key pair is generated for each badge or credential. The private key is encrypted and stored as described above. The badge starts in pending_first_use status.

On the first successful authentication, the badge transitions to active status and records the first-use timestamp.

Passphrase changes create a new version of the badge. The old envelope is replaced with a new one encrypted with the new passphrase. Version history is maintained for audit purposes.

When a badge is revoked (by admin action, device removal, or policy), its status changes to revoked with a timestamp and reason. The encrypted key envelope remains in the database for audit purposes but can no longer be used for authentication.

What the attacker gets: Encrypted key envelopes, server salts, device salt hashes, public keys.

What they can do: Nothing immediately. They cannot decrypt the private keys without both the device salt and the PIN. The device salt hash doesn’t help them derive the device salt (SHA-256 is one-way).

If they also obtain a device salt (e.g., by photographing a QR code): They can attempt offline PBKDF2 guessing against the PIN, limited by the 100,000-iteration work factor. A 6-digit PIN has 1,000,000 possibilities, which is feasible to brute-force offline. Longer passphrases (levels 3-4) provide stronger resistance.

The device salt is only useful if the attacker also has access to the server-stored envelope. Revoking the badge on the server invalidates the encrypted key, making the device salt useless even if recovered.

All authentication happens over HTTPS. The QR code contains a URL, not cryptographic material directly, so interception of the QR content alone doesn’t compromise security. The device salt is transmitted over the encrypted HTTPS connection during authentication.

Each authentication produces a unique signature over timestamped data. Replaying an old signature will fail because the timestamp won’t match the current authentication request.