I did an overkill deep-dive into the format after following Scott's links for funsies. TLDR:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...
| "ssh-rsa" |exponent| modulus
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFKy...
| "ssh-ed25519" | 32 byte public key
RFC4231 specifies the two data types used:
string
:
Arbitrary length binary string. Strings are allowed to contain
arbitrary binary data, including null characters and 8-bit
characters.
mpint
:
Represents multiple precision integers in two's complement format,
stored as a string, 8 bits per byte, MSB first. [...]
Both datatypes start with a uint32
defining the length of data to come. Because that's usually overkill and you end up with lots of 0's (e.g. "abc" is stored as \x00\x00\x00\x03abc
...), they end up as runs of A
s in the base64-encoded payload (...AAAAA2FiYwo
)
RFC4253 sec 6.6 says the key is encoded as:
The "ssh-rsa" key format has the following specific encoding:
string "ssh-rsa"
mpint e
mpint n
Here the 'e' and 'n' parameters form the signature key blob. [Ed: but the blob also seems to contain the string "ssh-rsa"
as well...]
The resulting signature is encoded as follows:
string "ssh-rsa"
string rsa_signature_blob
The value for 'rsa_signature_blob' is encoded as a string containing
s [Ed: don't know what s is.] (which is an integer, without lengths or padding, unsigned, and in
network byte order).
The more modern Ed25519 and Ed448 keys are defined in RFC-8709 and have two fields:
- the constant string "ssh-ed25519" (or "ssh-ed448")
- the 32-byte (or 57-byte) public key as a string
"ssh-rsa"
The string ssh-rsa
is converted to \x00\x00\x00\x07ssh-rsa
, which then encodes to AAAAB3NzaC1yc2E=
, so all ssh-rsa keys should start with that.
e
, the public exponent
Usually something like 3, 17, 257, 65537. Those numbers get encoded as below (with the trailing offset from above)
- 3 →
'\x00\x00\x00\x01\x03'
→ AAAABAw
- 17 →
'\x00\x00\x00\x01\x11'
→ AAAABEQ
- 257 →
'\x00\x00\x00\x02\x01\x01'
→ AAAACAQE
- 65537/0x10001 →
'\x00\x00\x00\x03\x01\x00\x01'
→ AAAADAQAB
So, if you see "BAw", your exponent was 3, or "DAQAB" = 65537
n
, the modulus (product of your two secret primes, factor this!)
AAABAQ
after the above means that your key length is 2048 bits (and that your exponent was like DAQAB because of base64 padding). The entire rest of the base64 stuff is the exponent, there's nothing after.
Other modulus prefixes that may be common:
AAAAg
1024 bits, e = 0x10001
AAAQI
: 2048 bits, e = 3