I'm looking to lock down our Solaris 10, RHEL 5, and SLES 11.2 servers. It has come to my attention that some of the users have no passphrase for their SSH keys. Is there a way I can check for this with a script?


Below I have posted the script I wrote from the answer @tylerl gave me. I'm posting this incase someone else needs this info in the future. There is most likely better ways to do this, but this works. I still need to write additional scripts for the accounts that are not automounted. Thanks everyone for all the help

# This script is for checking for a blank passphrase. Meaning no passphrase to secure your SSH key.
# Script most be run as root.
# Example: sudo ./check-sshkeys

mount share:/vol/home /mnt
ls /mnt >/tmp/ls
for s in `cat /tmp/ls`
do echo -e "\e[1m User $s \033[0m "

if ls /mnt/$s/.ssh/id_rsa 2>/dev/null
        then grep ENCRYPTED /mnt/$s/.ssh/id_rsa || echo -e "No RSA
        else echo "RSA key not found"
if ls /mnt/$s/.ssh/id_dsa 2>/dev/null
        then grep ENCRYPTED /mnt/$s/.ssh/id_dsa || echo -e "No DSA
        else echo "DSA key not found"
rm /tmp/ls
umount /mnt
  • 2
    Do you have access to the private key files? – Hauke Laging Mar 19 '14 at 15:31
  • @Hauke Laging, I have root, so yes I do have access. – Cyberninja Mar 19 '14 at 16:48
  • @Cyberninja Do you have root access to the clients? The server doesn't have the private key file. – Gilles 'SO- stop being evil' Mar 19 '14 at 23:05
  • @Gilles, The user should have there private key file in there home directory. All the home directories a automounted. I have root on all the servers I will be checking. I also have access to the NFS share. – Cyberninja Mar 20 '14 at 13:32
  • @Cyberninja The private key is in the home directory on the client. You haven't stated clearly whether you had any access to the clients. If their home directories are mounted by NFS, you have bigger things to worry about than whether people use passwords on their private key files. (Also, even if they do, the next step is to check what they're doing for a password manager. Then check what master password they're using.) – Gilles 'SO- stop being evil' Mar 20 '14 at 13:43

If you're checking from the server that people are connecting to, then no dice. The SSH key has to be decrypted in memory before use, which means to the server they look the same. Unless you can get a copy of the actual key file, you're sunk.

But if you're on the machine people are connecting from, well then it's trivial -- just look at the key file.

Passwords on SSH keys are used to encrypt the key, and the file indicates whether encryption is used as well as what type.

An encrypted private key looks like this:

Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,259001658E2E5C2618A9648EA35122F4


While an unencrypted one looks like this:


The trained eye might notice that the second line contains the word "ENCRYPTED". That's your clue. If the file contains the word "ENCRYPTED" then it is, if it doesn't then it's not.

So here's your script:

grep -L ENCRYPTED /home/*/.ssh/id_rsa

modify to suit your environment, but you get the idea. Obviously people could fool your script by put the word "ENCRYPTED" down at the bottom of the file, but we're assuming that they won't.

  • This looks like it might work. The Solaris server doesn't like the -L option and the * needs to be replaced by a variable. I tested it against my account and a known account with a blank key and it worked. – Cyberninja Mar 20 '14 at 13:49
  • This does not work with the new-style private key format used by OpenSSH 6.5 and later. Most keys you run across will be old-style since even with 6.5 that's the default format, but if you run across a key file beginning with -----BEGIN OPENSSH PRIVATE KEY----- you'll have to dig deeper to tell if it's encrypted. – Jander Nov 18 '14 at 1:07

The server can't know whether the key you're using to connect to it has a passphrase or not.

The passphrase is used to encrypt the SSH key for storage. When you use an SSH key, it is decrypted into memory using the passphrase so that it can be used to connect to the server. So the server has no way to tell whether the key being used was decrypted or not.

If the private keys are being stored on the server (rather than used to connect to the server), you can check that.

Tylerl's answer is the easiest way to find unencrypted keys, though it may break if OpenSSH introduces a new key format (which they did recently). An alternative is to use ssh-keygen to check, but that approach has its own problems.

It's difficult to script this check because the OpenSSH tools are really finicky about their keys, and they also really want to talk to the user if they find an encrypted key. Here's one (rough) way to check, if you have the setsid tool from the util-linux package:

if res="$(setsid </dev/null 2>&1 env -i ssh-keygen -y -f "$keyfile")" ; then
    echo "Unencrypted private key!"
    echo "Encrypted, or unreadable, or not a private key,"
    echo "or doesn't have correct permissions for a private key,"
    echo "or SSH doesn't like it for some reason."
    echo "More info that may or may not be helpful:"
    printf "%s\n" "$res"

If it says "Unencrypted private key!", you've definitely found one. If it doesn't, you can at least bet that if is an unencrypted key, SSH won't use it as it is.

(N.B. if you happen to find that /etc/ssh/ssh_host_rsa_key or the like is unencrypted, leave it alone -- it's supposed to be that way!)

  • 1
    Good point, it is important to understand the difference between private and public keys with a public key pair. The asker has not clarified this point, and we may be making incorrect assumptions when answering. – 0xSheepdog Mar 19 '14 at 16:03
  • The private and public keys are stored on the server. The public keys are used to access the UNIX serves from one of 2 admin servers. We have on account that uses the private key to access a Solaris server from a Windows machine. – Cyberninja Mar 19 '14 at 16:52
  • @Cyberninja No, the private key file is not stored on the server. (There may be a private key file on the server, but by definition, it isn't the one on the server.) – Gilles 'SO- stop being evil' Mar 19 '14 at 23:06
  • @Gilles, The users have id_rsa and id_rsa.pub files in there home directories. The home directories are auto mounted when the user logs in. I don't understand what your mean the key is not on the server. – Cyberninja Mar 20 '14 at 13:36
  • @Cyberninja The server has the public key. The client has the private key file, and computes the private key from the password and the private key file. – Gilles 'SO- stop being evil' Mar 20 '14 at 13:43
  1. You can just use the key within a script. Make sure that ssh does not use ssh-agent in that case: SSH_AUTH_SOCK=

  2. OpenSSH ssh-keygen can convert private keys but only if they do not have a passphrase. So you can just check for the exit code: ssh-keygen -f id_dsa -i


Caveat H@x0r - The actions provided in this example could be considered a violation of user privacy and sysadmin trust. This example is offered for your knowledge and understanding; YOU are responsible to ensure you have the authority, permission, and responsibility to take action based on these examples.

TL;DR > If you maliciously hack it, it's your ass...not mine.

If you have superuser privilege on the system with the private keyfile, you can test if there is a passphrase by attempting to change the existing passphrase. If the private key has a passphrase, you will be prompted for the old phrase before it allows you to change it. (Make sure you do not enter any text, just hit <Enter> when prompted for old passphrase.) Here is a demonstration:

### Example: trying to change passphrase when one already exists ###

$ sudo ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa): /home/bob/.ssh/id_rsa
Enter old passphrase: 
Bad passphrase.

No surprises there. Here's how to tell they have no passphrase configured.

### Example: trying to change passphrase, no phrase configured on key ###

$ sudo ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa): /home/bob/.ssh/id_rsa
Key has comment '/home/bob/.ssh/id_rsa'
Enter new passphrase (empty for no passphrase): 
  • That's and interesting idea but, I want to be able to script this. I have thought of doing something like this. I was going to become root, then become the user and try to ssh to a server. If I can login without putting in a passphrase then I know the passphrase is blank. I would also kill there agent if it was running. But then again if they have a agent running then they most likely don't have a blank passphrase. – Cyberninja Mar 19 '14 at 17:04
  • The answer from @bersch has some scripting code. You can script my example as well, if you can handle the outcome from the ssh-keygen and kill the command. – 0xSheepdog Mar 19 '14 at 17:13
  • 1
    This can be scripted using "expect". It emulates an interactive session from a script. – Juan Mar 19 '14 at 19:57
  • AH yes, expect... I knew there was a way, but it has been a long time since I've done any of that. Thanks @Juan, that was right on! – 0xSheepdog Mar 19 '14 at 20:35
  • Sorry I Haven't learned expect yet. – Cyberninja Mar 20 '14 at 13:56

I looked all over for this and never found a satisfying answer, but I managed to construct one, so...

Note that this will update the file if it works, so if you're trying to not be noticed by the users whose keys you're testing, you may want to copy the key first. OTOH, since you just caught your user with a passwordless key, maybe you don't care if they notice. :D

$ ssh-keygen -p -P '' -N '' -f ~/.ssh/KEYTEST
Key has comment '/home/rlpowell/.ssh/KEYTEST'
Your identification has been saved with the new passphrase.
$ echo $?

$ ssh-keygen -p -P '' -N '' -f ~/.ssh/KEYTEST
Bad passphrase.
$ echo $?

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