How to determine which cipher was used to encrypt OpenSSH private keys

Damien Miller djm at mindrot.org
Tue Jan 23 13:18:19 AEDT 2024


On Mon, 22 Jan 2024, Jakub Jelen wrote:

> Hi,
> looking through the key specification, you can see that its the second
> field in the key file:
> 
> https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key#L11
> 
> It looks like there is no convenient way to get this information with
> openssh cli, but given that the file format is just base64 encoded,
> you can read it out with something like this:
> 
> $ cat /tmp/rsa | head -n -1 | tail -n +2 | base64 -d | hexdump -C | head -n 2
> 00000000  6f 70 65 6e 73 73 68 2d  6b 65 79 2d 76 31 00 00  |openssh-key-v1..|
> 00000010  00 00 0a 61 65 73 32 35  36 2d 63 74 72 00 00 00  |...aes256-ctr...|
> 
> In this case, this key is aes256-ctr encrypted.

You could use something like the attached python script if you don't want
to stare at hexdumps :)
-------------- next part --------------
#!/usr/bin/env python3

import sys
import base64

BEGIN="-----BEGIN OPENSSH PRIVATE KEY-----\n"
END="\n-----END OPENSSH PRIVATE KEY-----"
BLOBSTART=b"openssh-key-v1\x00"

for f in sys.argv[1:]:
	d64 = open(f, "rt").read()
	o = d64.find(BEGIN)
	if o == -1:
		raise ValueError("{} missing begin marker".format(f))
	d64 = d64[o + len(BEGIN):]
	o = d64.find(END)
	if o == -1:
		raise ValueError("{} missing end marker".format(f))
	d64 = d64[:o]
	d = base64.b64decode(d64)
	if d[:len(BLOBSTART)] != BLOBSTART:
		raise ValueError("{} missing blob preamble".format(f))
	d = d[len(BLOBSTART):]
	l = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]
	alg = d[4: 4+l].decode("utf-8")
	print("{}: {}".format(f, alg))



More information about the openssh-unix-dev mailing list