~/.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
  • 2
    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. – Jakuje Aug 28 '16 at 12:00
up vote 16 down vote accepted

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
  • tmp="$(mktemp -t fingerprint-authkeys)" must be changed to tmp="$(mktemp -t fingerprint-authkeys.XXX)" – Stefan Sep 16 '10 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). – Chris Johnsen Sep 16 '10 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 – Stefan Sep 16 '10 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. – Alexander Pogrebnyak Sep 16 '10 at 11:40
  • 1
    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. – Jakuje Aug 28 '16 at 11:58

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.

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

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
  • Maybe the newer version of ssh-keygen can handle reading from a special file, because your one-liner works perfectly for me. – Brian Minton Jan 12 '16 at 14:18
  • Some versions like reading from stdin, others refuse to. Going through a normal file works everywhere. – Marcin Oct 25 '17 at 19:34

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

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.