go_sshkeys/_ref/ed25519/private/v1/plain.adoc

4.1 KiB
Raw Permalink Blame History

v1 (Plain)
Tip

Since plaintext/unencrypted keys do not have a cipher or KDF (as theres no encryption key or algorithm used), they use the string "none" to identify these (and entirely leave out the KDF options).

Structure
0.0 "openssh-key-v1" string plus terminating nullbyte (15 bytes)
1.0 uint32 allocator for 1.0.0 (4 bytes)
    1.0.0 cipher name string (ASCII bytes)
2.0 uint32 allocator for 2.0.0 (4 bytes)
    2.0.0 KDF name string (ASCII bytes)
3.0 uint32 allocator for KDF options (3.0.0 to 3.0.1) (4 bytes) (ALWAYS 0 for unencrypted keys, so no following substructure)
4.0 uint32 counter for # of keys (4 bytes)
    4.0.0 uint32 allocator for public key #n (4.0.0.0 to 4.0.0.1) (4 bytes)
        4.0.0.0 uint32 allocator for 4.0.0.0.0 (4 bytes)
            4.0.0.0.0 public key #n keytype string (ASCII bytes)
        4.0.0.1 uint32 allocator for 4.0.0.1.0 (4 bytes)
            4.0.0.1.0 public key #n payload (bytes)
    4.0.1 uint32 allocator for private key structure #n (4.0.1.0 to 4.0.1.5) (4 bytes)
        4.0.1.0 uint32 decryption "checksum" #1 (should match 4.0.1.1) (4 bytes)
        4.0.1.1 uint32 decryption "checksum" #2 (should match 4.0.1.0) (4 bytes)
        4.0.1.2 Copy of 4.0.0.0; allocator for 4.0.1.2.0 (4 bytes)
            4.0.1.2.0 Copy of 4.0.0.0.0 (ASCII bytes)
        4.0.1.3 Copy of 4.0.0.1; allocator for 4.0.1.3.0 (4 bytes)
            4.0.1.3.0 Copy of 4.0.0.1.0 (bytes)
        4.0.1.4 uint32 allocator for 4.0.1.4.0 (4 bytes)
            4.0.1.4.0 Private key #n (bytes)
        4.0.1.5 uint32 allocator for 4.0.1.5.0 (4 bytes)
            4.0.1.5.0 comment for key #n string (ASCII bytes)
        4.0.1.6 sequential padding
Note

Chunk 3.0.0 to 3.0.1: These blocks are not present in unencrypted keys (see the encrypted key structure for what these look like). 3.0 reflects this, as its always going to be 00000000 (0).

Chunk 4.0: This is technically currently unused; upstream hardcodes to 1 (left zero-padded 0x01).

Chunk 4.0.1.4.0: This is a 64-byte block for ED25519, but the second half of the private key ([32:]) is always the same as the public key.

Chunk 4.0.1.6: The padding used aligns the private key (4.0.1.0 to 4.0.1.5.0) to the cipher blocksize. For plaintext keys, a blocksize of 8 is used.

Example
id_ed25519 Format
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBEOIvJc2hN1mhXExEiv/ISyYO7prFixOl80R9zw52XsAAAAJjPbUqwz21K
sAAAAAtzc2gtZWQyNTUxOQAAACBEOIvJc2hN1mhXExEiv/ISyYO7prFixOl80R9zw52XsA
AAAEBqSF+KwoLTOqI6+TnpcaZY4ckcamLrBF8CvtJbNZflJ0Q4i8lzaE3WaFcTESK/8hLJ
g7umsWLE6XzRH3PDnZewAAAAElRoaXMgaXMgYSB0ZXN0IGtleQECAw==
-----END OPENSSH PRIVATE KEY-----
Structure Reference (Hex) (Decoded Base64)
0.0 6f70656e7373682d6b65792d763100 ("openssh-key-v1" + 0x00)
1.0 00000004 (4)
    1.0.0 6e6f6e65 ("none")
2.0 00000004
    2.0.0 6e6f6e65 ("none")
3.0 00000000 (0)
4.0 00000001 (1)
    4.0.0 00000033 (51)
        4.0.0.0 0000000b (11)
            4.0.0.0.0 7373682d65643235353139 ("ssh-ed25519")
        4.0.0.1 00000020 (32)
            4.0.0.1.0 44388bc973684dd66857131122bff212
                      c983bba6b162c4e97cd11f73c39d97b0 (bytes)
    4.0.1 00000098 (141)
        4.0.1.0 cf6d4ab0 (3480046256)
        4.0.1.1 cf6d4ab0 (3480046256)
        4.0.1.2 0000000b (11)
            4.0.1.2.0 7373682d65643235353139 ("ssh-ed25519")
        4.0.1.3 00000020 (32)
            4.0.1.3.0 44388bc973684dd66857131122bff212
                      c983bba6b162c4e97cd11f73c39d97b0 (bytes)
        4.0.1.4 00000040 (64)
            4.0.1.4.0 6a485f8ac282d33aa23af939e971a658
                      e1c91c6a62eb045f02bed25b3597e527
                      44388bc973684dd66857131122bff212
                      c983bba6b162c4e97cd11f73c39d97b0 (bytes)
        4.0.1.5 00000012 (18)
            4.0.1.5.0 5468697320697320612074657374206b6579 ("This is a test key")
        4.0.1.6 010203 ([1 2 3], 3 bytes)