19

~/.ssh/authorized_keys[2] contains the list of public keys.

Unfortunately, each public key does not specify the key strength ( number of bits ).

Is there a utility that can process this file line by line and output the key strength?

I checked man pages for ssh-keygen, but it looks like it would only work with private keys.

Also, is there a tool that would output sha1 hash the same way as it is displayed in pageant Putty tool?

The format I am looking for:

Key Algorithm Strength Hash Comment ssh-rsa 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff user1@host1 ssh-rsa 2048 11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11 user2@host2 
1
  • 4
    Note, that for openssh-7.2, you don't need to do the magic in the accepted answer anymore and you can just feed the ssh-keygen with the whole file. See my answer below. Commented Aug 28, 2016 at 12:00

5 Answers 5

17

ssh-keygen can do the core of the work (generating a fingerprint from a public key), but it will not automatically process a list of multiple keys as is usually found in an authorized_keys file.

Here is a script that splits up the keys, feeds them to ssh-keygen and produces the table you want:

#!/bin/sh # usage: authkeys-report <authorized_keys-file> set -ue tmp="$(mktemp -t fingerprint-authkeys.XXXXXXXX)" trap 'rm -f "$tmp"' 0 while read opts key; do case "$opts" in [0-9]*|ssh-dss|ssh-rsa) # not options, first "word" is part of key key="$opts $key" ;; esac echo "$key" >$tmp set -- $(ssh-keygen -lf "$tmp") bits="$1" fingerprint="$2" set -- $key # Note: will mangle whitespace in the comment case "$1" in [0-9]*) # SSH v1 key type=rsa1 shift 3 ;; ssh-rsa|ssh-dss) # SSH v2 key type="$1" shift 2 ;; *) type=unknown set -- ;; esac printf '%-14s %-9s %s %s\n' "$type" "$bits" "$fingerprint" "$*" done <$1 
8
  • tmp="$(mktemp -t fingerprint-authkeys)" must be changed to tmp="$(mktemp -t fingerprint-authkeys.XXX)" Commented Sep 16, 2010 at 9:03
  • 1
    @Stefan: Not all versions of mktemp(1) need the Xs: FreeBSD, Mac OS X. But, adding them will not hurt the behavior of those do not need them (they just end up with the Xs before the random suffix). Commented Sep 16, 2010 at 9:49
  • oh.. :) cool... i tried running the script on my arch box... kept saying /home/steve/.scripts/key-strength: line 36: $1: unbound variable Commented Sep 16, 2010 at 9:52
  • Thanks, -l option is really what I was looking for! Still it's unbelievable that you cannot pipe anything to ssh-keygen and MUST have file on disk. Commented Sep 16, 2010 at 11:40
  • 2
    Note, that for openssh-7.2, you don't need to do this magic anymore and you can just feed the ssh-keygen with the whole file. See my answer below. Commented Aug 28, 2016 at 11:58
15

ssh-keygen in openssh-7.2 (Currently in Fedora and Ubuntu Xenial at least) supports reading multiple keys from a single file. Therefore running simply

# ssh-keygen -l -f ~/.ssh/authorized_keys 2048 SHA256:xh0IVbI... jakuje@jakuje (RSA) 2048 SHA256:xh0IVbI... jakuje@jakuje (RSA) 

results in the desired output.

1
  • 2
    Good that they've finally fixed the deficiency. +1 Commented Aug 31, 2016 at 1:49
7

If you have zsh, you can do this as a one-liner:

while read line ; do ssh-keygen -lf =(echo $line); done < .ssh/authorized_keys 
4

extrapolating from the zsh solution a bash solution

while read line ; do ssh-keygen -l -f <(echo $line); done < .ssh/authorized_keys 

/dev/fd/63 is not a public key file.
/dev/fd/63 is not a public key file.

almost... This should work, but ssh-keygen seems not to like reading directly from the generated fd. Using a temp file for the <( redirection, it then works. Why?

while read line do cat > /tmp/key <(echo $line) ssh-keygen -l -f /tmp/key done < .ssh/authorized_keys 

1024 1f:c7:da:ef:ff:ff:ff:ff:c8:77:c6:f8:1f:dd:f3:1a /tmp/key (RSA)
3072 83:cd:af:b4:ff:ff:ff:ff:02:30:e7:1e:47:ed:c5:69 /tmp/key (RSA)

of course then you can more easily write this and be happy

while read line do echo $line > /tmp/key ssh-keygen -l -f /tmp/key done < .ssh/authorized_keys rm /tmp/key 
2
  • Maybe the newer version of ssh-keygen can handle reading from a special file, because your one-liner works perfectly for me. Commented Jan 12, 2016 at 14:18
  • Some versions like reading from stdin, others refuse to. Going through a normal file works everywhere. Commented Oct 25, 2017 at 19:34
3

Script to list all the finger prints from the authorized_keys file, created by saravana:

#!/usr/bin/ksh USER=`whoami` USER_H=` lsuser -a home $USER |awk -F '=' '{print $2}'` cat $USER_H/.ssh/authorized_keys| while read line do echo $line > /tmp/finger_print echo "************* Key,finger print details below ***************************" cat /tmp/finger_print echo ssh-keygen -l -f /tmp/finger_print|grep -v not|awk '{print $1" " $2 " " $4}' if ssh-keygen -l -f /tmp/finger_print|grep "is not a" > /dev/null 2>&1 then echo "The above key is an Invalid Key,Please correct it" fi echo "========================================================================" rm /tmp/finger_print done 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.