Hardware-grade PIN security — without the hardware.
A 4-digit PIN has only 10,000 combinations. Anywhere it guards data an attacker can copy — a browser, a file, a backup — they can brute-force it offline in milliseconds. VESlocker removes the offline attack entirely: the decryption key is split between the user's PIN and a secret held by a small key server, released only under a strict, exponentially-throttled budget. After a few dozen wrong guesses the entry is locked for good — a true lifetime cap on attempts, the way a TPM or a secure enclave behaves, in ~250 lines of vanilla JS and ~110 lines of PHP.
challenge = SHA-256(seed ‖ PIN) and sends only an id and that challenge to the key server — never the seed, the PIN, or the data.id secret, enforces the throttle (the next attempt is refused for 2^attempts seconds, capped), and returns key = SHA-256(secret ‖ challenge).AES-GCM(key). The ciphertext and the seed are kept locally; the key itself is never stored.id increments its counter. After ~32 attempts the wait exceeds a century — the entry is effectively sealed.<script src="https://veslocker.com/pub/VESlocker.js"></script>
<script>
const vl = new VESlocker({
apiUrl: "https://veslocker.com/api/VESlocker.php"
});
// Encrypt a secret behind a PIN and stash it under a name:
await vl.store("launch-codes", "1234", "the actual launch codes");
// Read it back with the PIN - throttled, and re-deposited under a
// fresh id + seed on every success:
const secret = await vl.fetch("launch-codes", "1234");
</script>
The client is Apache-2.0 — embed it with no copyleft obligations.
Prefer to manage storage yourself? encrypt / decrypt are stateless and return / take a self-contained token.
This demo talks to the public veslocker.com key server. Store a value behind a PIN, then fetch it back — and watch the throttle kick in after a few wrong PINs.
VESlocker is a key oracle gated by throttling, not a vault. Reason about it honestly before you deploy:
veslocker.com API endpoint and public JS library, as shown above.