ModernCalcs

SSH Key Pair Generator

Generate a real RSA key pair with a properly wire-formatted OpenSSH public key line, ready for authorized_keys.

SSH Key Pair Generator: A Real Wire-Format Public Key, Not Just a Raw Key

An SSH public key isn't just an RSA key — it's the key's exponent and modulus wrapped in a specific binary wire format (RFC 4253), the same format ssh-keygen itself produces. This tool generates a real RSA key pair via native Web Crypto and constructs that exact wire format by hand, so the output is a genuinely valid, immediately usable OpenSSH public key line.

Formula
ssh-rsa AAAA... = base64(string("ssh-rsa") + mpint(e) + mpint(n))

mpint: big-endian bytes, with a leading 0x00 prepended if the high bit would otherwise be set.

Verified Against a Real ssh-keygen Output

The wire-format encoding logic in this tool was checked by decoding a real ssh-keygen-generated public key back into its raw exponent and modulus, then re-encoding those same values using this tool's exact algorithm — the result matched the original byte-for-byte. This is the same practical confidence check you'd want from any hand-implemented binary format.

Why mpint Encoding Has a Specific Gotcha

SSH's mpint format represents integers as big-endian bytes, but with one rule that's easy to miss: if the most significant bit of the first byte is set, a 0x00 byte must be prepended — otherwise the value would be misinterpreted as negative by anything reading it as a signed integer. RSA moduli are large enough that this edge case comes up in practice, not just in theory.

PKCS8 vs. OpenSSH Private Key Format

OpenSSH has its own private key container format, distinct from the more universal PKCS8 standard that Web Crypto natively exports. This matters less than it used to — OpenSSH 7.8 (released 2018) and later accept PKCS8 keys directly, so in practice this is a non-issue for any reasonably current SSH client.

Practical Examples

Adding a Key to a Server

Standard authorized_keys workflow.

  • 1.Generate the key pair
  • 2.Copy the public key line
  • 3.Append to ~/.ssh/authorized_keys on the server

Adding a Key to GitHub/GitLab

Same public key format, different destination.

  • 1.Copy the public key line
  • 2.Paste into GitHub Settings → SSH Keys
  • 3.Add a matching private key to your local SSH agent

What This Tool Generates

  • Real RSA key pair: via native Web Crypto
  • Genuine OpenSSH wire-format public key line
  • PKCS8 PEM private key
  • Configurable comment and key size

Good Use Cases

  • Generating a quick SSH key pair without a terminal
  • Adding a new key to a server's authorized_keys
  • Learning how SSH's public key wire format actually works
  • Generating test key pairs for SSH-related tooling

Frequently Asked Questions

Is the public key really in valid OpenSSH format?

Yes — it's built using the exact binary wire format OpenSSH uses (RFC 4253): a length-prefixed 'ssh-rsa' type string followed by length-prefixed mpint-encoded exponent and modulus, base64-encoded. This was verified against a real ssh-keygen-generated key during development, producing byte-for-byte identical output for the same key material.

Can I paste this directly into authorized_keys?

Yes — the public key line this tool produces is a complete, standard OpenSSH public key entry, in exactly the format authorized_keys, GitHub/GitLab SSH key settings, and ssh-keygen itself all expect.

Why is the private key PKCS8 instead of the OpenSSH private key format?

Web Crypto's native key export only supports standard formats like PKCS8, not OpenSSH's own private key container. The good news: OpenSSH 7.8 and later accept PKCS8-format private keys directly, so this is usable as-is with any reasonably modern SSH client — older clients can convert it with a single ssh-keygen command.

What is mpint encoding, and why does it matter?

It's how SSH's wire format represents large integers (the RSA modulus and exponent): a big-endian byte sequence, with a leading zero byte prepended if the value's high bit would otherwise be set (to avoid it being misread as a negative number). Getting this detail wrong produces a public key that looks plausible but fails to parse or produces the wrong fingerprint.

Why does the comment field matter?

The comment (typically an email or hostname) is purely informational — it has no cryptographic role and doesn't affect the key's function. It's there to help you (or a server admin) identify which key is which when looking at a list of authorized keys.

Is my private key sent anywhere?

No, key generation and formatting both happen entirely in your browser via the Web Crypto API — private key material never leaves your device.