Is there a way to check a users SSH key to see if the passphrase is blank

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:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,259001658E2E5C2618A9648EA35122F4

GFzPnlYdGYVTmK5t45xv/m0Nok9czOuFNNuS+Sm5vzGaOa7LBMtRNJgWFBCGsfFl
wouThpuKxV+ArgmzPa9hnEmy18QW0sbza8SKm/3Hbqi8XwCliz2xP2xS+iGSkYDt
...
LAB/DZasuYBSsVadfemDsmrRvUz7/4eJZTxoEvwNQtAWhTS8j9RbRPee4rk1fwew
-----END RSA PRIVATE KEY-----

While an unencrypted one looks like this:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtdKjJa18HbagmuMvb/gDCpXXYPVqRsXDdwTcG3YY5RlJtdxY
TJD+626tLTyuzzw6ZsGJtScrSjm2Jp5uUrDXnkek39Zxj24bTM9k/tZBeAQubrwO
....
I8u05jPL1WZmre5SVexfFEvAGqMdiWLvURpnQkI7Wn6nXJjEbUOdGQ==
-----END RSA PRIVATE KEY-----

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.


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!"
else
    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"
fi

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!)

Tags:

Ssh

Ssh Agent