Skip to content

Instantly share code, notes, and snippets.

@MikaelSvenn
Last active January 24, 2018 22:18
Show Gist options
  • Save MikaelSvenn/e85f8e4d13e78e578d7c5fca7b3b9864 to your computer and use it in GitHub Desktop.
Save MikaelSvenn/e85f8e4d13e78e578d7c5fca7b3b9864 to your computer and use it in GitHub Desktop.
OPENSSH-PRIVATEKEY FORMAT for non encrypted ssh-ed25519
https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
https://github.com/openssh/openssh-portable/blob/master/sshkey.c :2957
https://github.com/openssh/openssh-portable/blob/master/cipher.c
https://github.com/openssh/openssh-portable/blob/master/sshbuf-getput-basic.c
OpenSSH key format prefixes most content with content length (uint32 + data).
All integers in OpenSSH key are encoded in big endian.
Example of openssh private key:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBR9Lbe0t6wCRKmdIwh60bMST4a3VDK0evaUT52cq13cAAAAJCOEs5NjhLO
TQAAAAtzc2gtZWQyNTUxOQAAACBR9Lbe0t6wCRKmdIwh60bMST4a3VDK0evaUT52cq13cA
AAAEADkfVQs1I16Y0LdQVJxTZPlRAwA7qTqu0y0lFCT/hRoFH0tt7S3rAJEqZ0jCHrRsxJ
PhrdUMrR69pRPnZyrXdwAAAAC29wZW5zc2gta2V5AQI=
-----END OPENSSH PRIVATE KEY-----
Example of the corresponding public key:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFH0tt7S3rAJEqZ0jCHrRsxJPhrdUMrR69pRPnZyrXdw openssh-key
OpenSSH utilizes Edwards curve representation for the Curve25519. Some libraries, such as BouncyCastle creates and handles Curve25519 keys in Weierstrass form. Different ECC representations are not directly interoperable and the public key (X,Y coordinates) need to be converted to Edwards form prior to OpenSSH key format. In case of BouncyCastle, the conversion would be Weierstrass -> Montgomery -> Edwards. The private key does not need conversions, as it is basically a multiplier. Pre-built libraries exist that can construct the public key primitives in Montgomery or Edwards representation based on the private key, such as Chaos.NaCl.
The private key format is vaguely defined in PROTOCOL.key. The key consists of
- Public, non-encrypted header with public key.
- Private, optionally encrypted private key container.
One OpenSSH private key file can contain multiple keys, although even OpenSSH appears to implement only one key per file. The format appears to be verbose and repeat the public key information multiple times.
Annotation:
- [L] = prefix content with the content length (uint32[BigEndian] + data)
- N = 32-bit number
- B = 8-bit number
- {} = binary content
e.g. L{} = length of the next content as a whole + the content.
The descriptions below represent a write order of content to the expected write buffer.
OpenSSH Public key:
-------------------
ssh-ed25519 {publickeyblob} consists of:
1) [L]"ssh-ed25519"
2) [L]{q}
where {q} is the 32-byte public key in Edwards form.
OpenSSH Private key blob:
-------------------------
ssh-ed25519 {privatekeyblob} consists of:
1) {pq}
where {pq} is a 64-byte private key concatenating the private key (32-byte) and the public key (32-byte), without length.
OpenSSH Private key structure as a whole:
-----------------------------------------
//HEADER
1) "openssh-key-v1\0" // key format version
2) [L]"none" // cipher name
3) [L]"none" // kdf name
4) [L]"" // kdf options
5) 1 // number of keys (BigEndian)
6) [L]{publickeyblob} // public key with the length of the whole blob
7) N // length of the rest of the write buffer in BigEndian
//CONTENT
8) N // checksum (random 32bit integer)
9) N // checksum (the exactly same integer as in previous step)
10) [L]"ssh-ed25519" // key type identifier
11) [L]{q} // 32-byte publickey (just the key material)
12) [L]{privatekeyblob} // 64-byte private key blob
13) [L]{comment} // sshkey comment associated with the key
14) B,B,B... // padding (1,2,3,...)
The padding is an 8-bit iterator that is incremented until the whole content-part is a multiple of the selected encryption cipher block size. For non-encrypted keys, the cipher size is defined to be 8.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment