Let's say I have access to the private portion of an RSA key-pair. How can I check if this key has associated passphrase or not?

  • 17
    trying to use it – Ay0 Jul 11 '16 at 11:44
  • 4
    @Ayozint Now sit back and wait for the questions on how to set up a dummy ssh server for the purpose, and how to kill a ssh process prematurely from a script after matching the string asking for a password. – nitro2k01 Jul 12 '16 at 14:57

The keyfile will have a different header if it is password protected. Here's the top of a key without a passphrase:


And here's the top of a key which is passphrase-protected:

Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,556C1115CDA822F5


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.

  • 3
    A solution based on the timing could work. In case of an unencrypted key, the response is usually sent instantly as soon as the server sends the challenge, where as for an encrypted one it takes at least a few seconds for the user to enter the passphrase to decrypt the key. – André Borie Jul 12 '16 at 0:04
  • 8
    @AndreBorie, unfortunately the client can't be trusted. Normal usage may have no delay if a key agent is caching the (phrased) key, and a malicious client could introduce fake delays to "mimic" unlocking the key... We went through the same thing 20 years ago with "timing analysis of password entry" on protocols like telnet :) – gowenfawr Jul 12 '16 at 0:25
  • 10
    More generally, encryption of the key is a totally client-side operation. If you want to know that the key is encrypted, it needs to live and be decrypted server-side. But then the server has the decrypted private key, which rather defeats the point of asymmetric cryptography. – Kevin Jul 12 '16 at 4:08
  • 3
    This answer is not correct (anymore). A priv key not showing the proc-type and DEK headers can very well be encrypted. – GerardJP Feb 7 '19 at 13:27
  • @GerardJP I interpret the answer as saying that if the proc-type and DEK header lines are missing, then it is not password protected. I don't think it is talking about whether or not something is encrypted. – bgoodr Dec 20 '19 at 22:03

It is not always so easy as described in the other answers. It works only with the old PEM keys. New openssh format of the keys (generated with -o option, more secure, since openssh-6.5) looks the same if you check the headers:

$ head rsa_enc
$ head rsa

The easiest way in this case is to run some operation on them using ssh-keygen. If it will ask for a passphrase, it has one (or it is not a ssh key), if not it does not have a passphrase:

$ ssh-keygen -yf rsa_enc
Enter passphrase: 
$ ssh-keygen -yf rsa
ssh-rsa AAAAB3NzaC1y...

Maybe even better is the following example, since it doesn't ask for input: -P specifies the passphrase to use, an unprotected key opens with an empty passphrase.

$ ssh-keygen -y -P "" -f rsa_enc
Load key "path_to_key": incorrect passphrase supplied to decrypt private key`
$ ssh-keygen -y -P "" -f rsa
ssh-rsa AAAAB3NzaC1y...
  • More secure but less compatible: they perceived the fact that the known ASN.1 structure was also encrypted as facilitating the brute-force attacks, and therefore left out the standard storage to create their own storage format where the attacker can rely on no previously known text. Thanks! – WhiteWinterWolf Jul 11 '16 at 13:20
  • 30
    The base64-encoded data does contain information about whether the key is encrypted, though: The first decodes to openssh-key-v1.....aes256-cbc....bcrypt.........v.. and the second decodes to openssh-key-v1.....none....none................ssh- – Random832 Jul 11 '16 at 15:34
  • @Random832 you are right. Thanks. But it is not so obvious as in the first case where it is in ASCII. – Jakuje Jul 11 '16 at 15:36
  • Well, base64 always maps three input characters to four output characters, so there is a chance that you could spot the encoded non or one of none, depending on what the exact offset of that string in the file is. – Ulrich Schwarz Jul 12 '16 at 5:28
  • 1
    And in 2018 (beginning with 7.8) new format is now the default and -o is not needed (you can still get old=OpenSSL format except for ed25519 with -m pem) FWIW PuTTY has its own 'ppk' format (also text+base64, but not PEM) with the second line specifying encryption or not. – dave_thompson_085 Feb 11 '19 at 4:56

The "RSA key" is actually a set of values stored as an ASN.1 structure in the standardized DER binary format, then encoded in base-64 to get the final PEM file.

A very easy way to determine whether a key is encoded or not is simply to check whether the ASN.1 header is present, and this is usually as simple as checking if the "key" begins with the letters MII as in the example below:


In password protected files, the whole ASN.1 structure being encrypted, it all appears as random characters.

  • 1
    But this could lead to false positives if the encrypted string also starts with MII ? – Falco Jul 11 '16 at 13:49
  • 4
    @Falco: Yes. On a practical basis, it is a good heuristic for instance to quickly check a set of unknown keys, but the only way to have a 100% guaranty about the key status (encrypted, corrupted, etc.) is by by using the method provided in Jakuje's answer (ssh-keygen -yf <keyfile>). – WhiteWinterWolf Jul 11 '16 at 15:12
  • Simpler and robust: OpenSSL 'traditional' format PEM-level encryption has two header lines plus a blank line before the encrypted&base64'd data, as shown in gowenfawr's answe – dave_thompson_085 Feb 11 '19 at 4:52

Private keys should be secured, trying to set the password just declares if it is yet password protected. With ssh-keygen on the protected key:

~/.ssh$ ssh-keygen -p -f id_rsa_password_protected
Enter old passphrase:

And with not protected:

~/.ssh$ ssh-keygen -p -f id_rsa_not_protected
Enter new passphrase (empty for no passphrase):

So if it is not password protected, just set the password.


While the other answers give valid answers to achieve this manually, the following approach can be used within a shell script for automation.

The following command's exit code determines whether the key file found at $path_to_keyfile has a password:

ssh-keygen -y -P "" -f "$path_to_keyfile" &>/dev/null

To use this command within a script that checks for this you could either use the following snippet

if ssh-keygen -y -P "" -f "$path_to_keyfile" &>/dev/null; then
    echo "unprotected"
    echo "protected"

or use && and || as shorthands like so:

ssh-keygen -y -P "" -f "$path_to_keyfile" &>/dev/null && echo "Unprotected" || echo "Protected"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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