The keyfile will have a different header if it is password protected. Here's the top of a key without a passphrase:
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA3qKD/4PAc6PMb1yCckTduFl5fA1OpURLR5Z+T4xY1JQt3eTM
And here's the top of a key which is passphrase-protected:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,556C1115CDA822F5
AHi/3++6PEIBv4kfpM57McyoSAAaT2ECxNOA5DRKxJQ9pr2D3aUeMBaBfWGrxd/Q
Unfortunately, that only works looking at the files. I know of no way for a server to be able to tell if the keys being presented to it were protected with a passphrase, which is the most useful place to be able to leverage that sort of info.
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!)