Given keys in ~/.ssh/authorized_keys format, can you determine key strength easily?

19,086

Solution 1

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

Solution 2

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.

Solution 3

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

Solution 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

Solution 5

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
Share:
19,086

Related videos on Youtube

Alexander Pogrebnyak
Author by

Alexander Pogrebnyak

Updated on September 17, 2022

Comments

  • Alexander Pogrebnyak
    Alexander Pogrebnyak over 1 year

    ~/.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
    
    • Admin
      Admin over 7 years
      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.
  • Stefan
    Stefan over 13 years
    tmp="$(mktemp -t fingerprint-authkeys)" must be changed to tmp="$(mktemp -t fingerprint-authkeys.XXX)"
  • Chris Johnsen
    Chris Johnsen over 13 years
    @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).
  • Stefan
    Stefan over 13 years
    oh.. :) cool... i tried running the script on my arch box... kept saying /home/steve/.scripts/key-strength: line 36: $1: unbound variable
  • Alexander Pogrebnyak
    Alexander Pogrebnyak over 13 years
    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.
  • Chris Johnsen
    Chris Johnsen over 13 years
    Stefan: Ahh, the $1 unbound error was because the scripts expects the path to an authorized_keys file as its argument. I should have made that explicit.
  • htho
    htho about 12 years
    Thanks for a great answer Chris! I took the liberty of adding a tiny bit of polish to your script and adding it to my ssh-config github repository. Anyone who wants to use this version can simply download the raw file and save it somewhere in their $PATH.
  • Kornelis
    Kornelis over 8 years
    Maybe the newer version of ssh-keygen can handle reading from a special file, because your one-liner works perfectly for me.
  • Jakuje
    Jakuje over 7 years
    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.
  • Alexander Pogrebnyak
    Alexander Pogrebnyak over 7 years
    Good that they've finally fixed the deficiency. +1
  • BrettRobi
    BrettRobi over 6 years
    Some versions like reading from stdin, others refuse to. Going through a normal file works everywhere.
  • kevr
    kevr about 2 years
    You can pipe data to ssh-keygen: cat id_ecdsa.pub | ssh-keygen -l -f -