How to get all fingerprints for .ssh/authorized_keys(2) file
Solution 1
Here's another hack using plain bash without temporary files:
while read l; do
[[ -n $l && ${l###} = $l ]] && ssh-keygen -l -f /dev/stdin <<<$l;
done < .ssh/authorized_keys
You can easily make it a function in your .bashrc
:
function fingerprints() {
local file="${1:-$HOME/.ssh/authorized_keys}"
while read l; do
[[ -n $l && ${l###} = $l ]] && ssh-keygen -l -f /dev/stdin <<<$l
done < "${file}"
}
and call it with:
$ fingerprints .ssh/authorized_keys
Solution 2
A one-liner based on the /dev/stdin trick from ℝaphink's answer and man xargs → EXAMPLES:
egrep '^[^#]' ~/.ssh/authorized_keys | xargs -n1 -I% bash -c 'ssh-keygen -l -f /dev/stdin <<<"%"'
Solution 3
Here's a portable way to show all key fingerprints for a given file, tested on Mac and Linux:
#!/bin/bash
fingerprint_keys()
{
if (( $# != 1 )); then
echo "Usage: ${FUNCNAME} <authorized keys file>" >&2
return 1
fi
local file="$1"
if [ ! -r "$file" ]; then
echo "${FUNCNAME}: File '${file}' does not exist or isn't readable." >&2
return 1
fi
# Must be declared /before/ assignment, because of bash weirdness, in
# order to get exit code in $?.
local TMPFILE
TEMPFILE=$(mktemp -q -t "$0.XXXXXXXXXX")
if (( $? != 0 )); then
echo "${FUNCNAME}: Can't create temporary file." >&2
return 1
fi
while read line; do
# Make sure lone isn't a comment or blank.
if [[ -n "$line" ]] && [ "${line###}" == "$line" ]; then
# Insert key into temporary file (ignoring noclobber).
echo "$line" >| "$TEMPFILE"
# Fingerprint time.
ssh-keygen -l -f "$TEMPFILE"
# OVerwrite the file ASAP (ignoring noclobber) to not leave keys
# sitting in temp files.
>| "$TEMPFILE"
fi
done < "$file"
rm -f "$TEMPFILE"
if (( $? != 0 )); then
echo "${FUNCNAME}: Failed to remove temporary file." >&2
return 1
fi
}
Example Usage:
bash $ fingerprint_keys ~/.ssh/authorized_keys
2048 xx:xx:xx:xx:xx:xx:xx:xx:bb:xx:xx:xx:xx:xx:xx:xx [email protected] (RSA)
bash $
Solution 4
ssh-keygen -l -f - <authorized_keys
produces a nice listing for you:
# ssh-keygen -l -f - <authorized_keys
2048 SHA256:GzZ7.................................RqTEag foo (RSA)
2048 SHA256:/y0.......................................4 bar (RSA)
2048 SHA256:p.........................................k bleech (RSA)
Solution 5
And should anyone need to do it on Windows / in PowerShell:
gc authorized_keys | foreach {$_ |ssh-keygen -l -f -}
or the fully-blown version without aliases looking for your user profile directory:
(Get-Content ((Get-Content env:/userprofile)+"/.ssh/authorized_keys")) | foreach {$_ |ssh-keygen -l -f -}
Related videos on Youtube
Comments
-
childno͡.de almost 2 years
Is there a simple way to get a list of all fingerprints entered in the .ssh/authorized_keys || .ssh/authorized_keys2 file?
ssh-keygen -l -f .ssh/authorized_keys
will only return fingerprint of first line / entry / publickey
hack with awk:
awk 'BEGIN { while (getline < ".ssh/authorized_keys") { if ($1!~"ssh-(r|d)sa") {continue} print "Fingerprint for "$3 system("echo " "\""$0"\"> /tmp/authorizedPublicKey.scan; \ ssh-keygen -l -f /tmp/authorizedPublicKey.scan; \ rm /tmp/authorizedPublicKey.scan" ) } }'
but is there an easier way or ssh command I didn't find?
-
Admin about 2 yearsPlease consider updating this question. Your command,
ssh-keygen -l -f .ssh/authorized_keys
, now seems to fingerprint all keys in the file, at least with my version (OpenSSH_8.4p1). No need for hacky oneliners anymore!
-
-
childno͡.de almost 12 yearsnice @Raphink , thank you. added code.childno.de/marcel/changeset/afdce0dd ;) One note:
ssh-keygen -l -f /dev/stdin
seems not to work on a mac.. nevertheless not relevant for servers but gnaa apple or is it a BSD "problem" getting/dev/stdin is not a public key file.
?! -
BJladu4 almost 12 yearsReading from
/dev/stdin
is not a great idea in general, it's better to use-
, but for some reasonssh-keygen
doesn't know about-
... -
Will almost 10 yearsDoesn't work on Mac?
-
childno͡.de almost 10 yearssorry to say that but that's neither "simplier", nor "smaller" not even "smarter" and doesn't take another approach than listed above. just a script using more error handlers ;)
-
Will almost 10 yearsWhich makes it safer, right? You're welcome to make edits but why downvote? I didn't propose that it was any kind of better solution than yours... I feel a secure tempfile is better, and that more safety is needed for scripting purposes. Also, the version above is noclobber-safe.
-
derekv almost 9 yearsFor a FreeBSD system (which does not use bash by default), I made the following changes: Assuming bash is installed from ports, change the first line to
#!/usr/local/bin/bash
. I then called the function by adding this as the last line:fingerprint_keys $@
. I saved the script asfingerprints.bash
, marking it executable withchmod u+x ./fingerprints.bash
. Additionally, I added a comment to the file with the link to this answer, like so, near the top# solution from "Will" on SO http://serverfault.com/a/615892/126742
. Call it like so./fingerprints.bash ~/.ssh/authorized_keys
. -
starfry over 7 yearsThis does not work if the keys are prefixed with options.
-
0xC0000022L almost 7 years@derekv: the more portable method is to use the following hashbang:
#!/usr/bin/env bash
, because the path forenv
is very portable and it tellsenv
to execute the Bash it knows about. -
0xC0000022L almost 7 years@ℝaphink: I'd go for
local file="${1:-$HOME/.ssh/authorized_keys}"
to allow for it to work without any arguments and default to the usual~/.ssh/authorized_keys
file and quote the< "$file"
used as input to thewhile
loop. -
Thibaut Barrère over 6 yearsThis works great, and given it's a one-liner, can easily be used to run the command via SSH. Thanks!
-
thomas over 4 yearsdoes not work with zsh
-
thomas over 4 yearsdoes not work with options field present in authorized_keys
-
thomas over 4 yearsthis works for me:
grep -o 'ssh-.*' ~/.ssh/authorized_keys | xargs -n1 -I% sh -c 'echo "%" | ssh-keygen -l -f /dev/stdin'
-
thomas over 4 yearsthis works for me with prefixed options:
grep -o 'ssh-.*' ~/.ssh/authorized_keys | xargs -n1 -I% sh -c 'echo "%" | ssh-keygen -l -f /dev/stdin'
-
tripleee over 2 yearsThe temporary file and all the machinations around it seem useless here; like most modern commands,
ssh-keygen -l -f -
reads from standard input just fine. Perhaps there was a time when it didn't, but then Bash provides/dev/stdin
for those cases. -
tripleee over 2 years
/dev/stdin
is a Bashism too; it is not guaranteed to work in non-Bash shells. Some OS platforms provide it, but not all. -
djdomi over 2 yearsthat is already shown in the hoghest count answer? did you not read it?
-
Admin about 2 yearsIts a little different @djdomi in that is using stdin (the
-
) arg, which I was able to use like thiscat ~/.ssh/authorized_keys | ssh-keygen -lf -
. -
Admin about 2 yearsIt seems that there's no need to do something different anymore though. While the OP says that command will fingerprint the first key in the file only, I've just run it now and got fingerprints for all of them:
wilmer@fiona:~$ ssh-keygen -l -f .ssh/authorized_keys
2048 SHA256:DEtyZ1E+22Gsx9g/k8Wdz2vMk3JyJ9ZgCxytb4aMYSc yubikey-ws-wilmer (RSA)
2048 SHA256:oIePQpcOShOhFlCIXZZv6wUCp96iX7Pg8cdFtTSb8Co yubikey-lap-wilmer (RSA)
.....