Question

I am trying to call ssh-keygen using a variable through bash as an input instead of a file to get a fingerprint of a public key. I am aware that I could use a temp file to get around this issue, but for reasons out of scope of this question, I do not want to.

This method does not work as it says the key file is invalid (it's correct for sure)

echo $pubkey | ssh-keygen -lf /dev/stdin

This does work, but is not using a variable, rather a file.

ssh-keygen -lf alpha.pub

This does work, but is not using a variable, rather a redirected file.

ssh-keygen -lf /dev/stdin < alpha.pub

This does not work because I get an ambiguous redirect

ssh-keygen -lf /dev/stdin < $(echo $pubkey)

I would appreciate some insight as to how to get ssh-keygen to read from a variable with a public key and if possible, an explanation as to why the redirects aren't doing what I think they should be doing. In specific why the | behaves differently than the < and why the third example is an ambiguous redirect. I searched online but many of the redirect tutorials didn't seem to answer my questions.

Was it helpful?

Solution

echo $pubkey | ssh-keygen -lf /dev/stdin
/dev/stdin is not a public key file.

/dev/stdin is actually a unix pipe, not a regular file, so ssh-keygen fails to open the file

ssh-keygen -lf /dev/stdin  <<<$key
1024 92:6a:3f:5c:1f:78:.....

/dev/stdin refers to a regular file, created by using a bash heredoc. You can verify this:

# ls -l /dev/stdin <<<$pubkey
lrwxrwxrwx 1 root root 15 Feb 11 08:07 /dev/stdin -> /proc/self/fd/0
# ls -l /proc/self/fd/0 <<<$pubkey
lr-x------ 1 juergen juergen 64 Apr 14 13:31 /proc/self/fd/0 -> /tmp/sh-thd-1271250023 (deleted)

OTHER TIPS

Since version 7.2 (released on on 2016-02-28), this is now possible by passing - as the file name. From the release notes:

  • ssh-keygen(1): allow fingerprinting from standard input, e.g. ssh-keygen -lf -

If you want to redirect a string as stdin, use this syntax:

cmd <<< "some $STR here"

If you want to redirect the output of a command as if it was a file, you do it like this:

cmd <( /bin/somecmd )

And if you want to use a command as an OUTPUT file, it's more or less the same:

cmd >( /bin/othercmd )

Here is a one liner using the file /dev/stdin as described in other answers.

$ ssh-keygen -lf /dev/stdin <<< $( ssh-keygen -f ~/.ssh/keyname.pem -y )
2048 14:df:c7:b7:f1:26:7f:87:d5:e7:10:6c:ac:af:a2:03 /dev/stdin (RSA)

Note that this will break with private keys that use a passphrase. It will work with pem files generated by AWS or OpenStack which do not use passphrases.

I would recommend using a temporary file. The issue is that redirecting, BASH expects a file. By using $(echo $pubkey), bash will complain because when it's done with the substitution, it will look for a file of that name that the substitution creates.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top