WireGuard Key Generator
A Curve25519 key pair in WireGuard's base64 format, plus an optional preshared key.
$ wg genkey | tee private.key | wg pubkey
What these keys are
A WireGuard peer is identified by a Curve25519 key pair. The private key stays in the [Interface] section of that peer's config and never moves; the public key is what you hand to the other side, where it goes in a [Peer] block. Both are printed as 32 raw bytes in standard base64 — a 44-character string ending in =. That is the entire identity system: no certificates, no authority, no expiry.
Is generating them in a browser reasonable?
Here the honest answer is unusually favourable. The pair comes from your browser's own crypto.subtle.generateKey('X25519') — the same audited native code your TLS connections use — and the private key is never transmitted or stored. You can verify it in the network tab, or simply disconnect from the network and watch this page keep generating. The usual objection to browser key generation is that you must trust the page you loaded; that objection is real, and it is why the SSH page tells you to prefer ssh-keygen for a long-lived production key. WireGuard keys are cheaper to rotate than an SSH identity — you change one line on each side — so the calculus is different, but the rule still holds: for a gateway that guards a production network, run wg genkey yourself.
The preshared key is not a password
The optional preshared key is 32 random bytes mixed into the handshake on top of the Curve25519 exchange. Its only job is post-quantum hedging: it means an adversary recording your traffic today cannot decrypt it later with a quantum computer, even if Curve25519 falls. It is symmetric, so the same value goes on both peers, and it adds nothing against a classical attacker. Skip it unless you have a long-term confidentiality requirement.
Is this the same as wg genkey?
Yes. wg genkey emits 32 random bytes as a clamped Curve25519 scalar in standard base64, and wg pubkey derives the matching public key — which is exactly what this page produces via your browser's crypto.subtle.generateKey('X25519'). The values are interchangeable: paste them straight into a WireGuard config.
Do I need the preshared key?
Probably not. It is a post-quantum hedge: 32 symmetric bytes mixed into the handshake so that traffic recorded today cannot be decrypted later by a quantum computer. It adds nothing against a classical attacker, and the same value must be configured on both peers. Add it only if you have a long-term confidentiality requirement.
Should I generate a production gateway key here?
Our honest answer: run wg genkey yourself for a gateway that guards a production network. The key pair here never leaves your browser and you can prove that by disconnecting your network, but you are still trusting the page you loaded. WireGuard keys are cheap to rotate — one line per side — so this page is well suited to test peers, lab setups and throwaway tunnels.
Nothing leaves your browser
- Don't take our word for it — turn off your wifi. Every generator on this site keeps working with the network disconnected. That's the whole proof, and it takes five seconds.
- Every value comes from
crypto.getRandomValues()— the CSPRNG built into your browser, neverMath.random(). - Generated secrets are never transmitted, logged or stored: no server-side generation, no cookies, no localStorage.
- Verify it yourself in the network tab: after loading, the page only talks to our self-hosted, cookie-less analytics — which counts page views and which generator type gets copied, never any value.
- Strict Content-Security-Policy; no third-party script origins.