SSH: hardening your keys with PKCS#8
In two or three commands:
$ mv ~/.ssh/id_rsa ~/.ssh/id_rsa.old
$ openssl pkcs8 -topk8 -v2 des3 -in ~/.ssh/id_rsa.old -out ~/.ssh/id_rsa
$ chmod 600 ~/.ssh/id_rsa
# Check that the converted key works; if yes, delete the old one:
$ rm ~/.ssh/id_rsa.old
And a small script to do it on the fly:
#!/bin/bash
: << 'TITLE.sh'
Version: 0.1
Authors: nobody@vhalholl.info
Description: hardening ssh private key w/ pkcs#8
http://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html
Dependencies: openssl
TITLE.sh
DEP=$(which openssl);[ ! -z $DEP ]&& {
for k in $(echo $(for i in $(ls *);do file $i; done |grep private |cut -d : -f1));do
echo "backup $k"; mv $k .$k.old
echo "convert $k"; openssl pkcs8 -topk8 -v2 des3 -in .$k.old -out $k; chmod 600 $k
done;
exit 0;
}
echo "Openssl not found" && exit 1
PKCS#8 wraps the RSA private key in a 3DES encryption layer with a hardened KDF (PBKDF2). The key’s passphrase becomes more expensive to brute-force: every decryption attempt requires extra KDF iterations. Same principle as bcrypt or scrypt for passwords, applied to SSH keys.
The conversion is transparent for SSH: the key works exactly as before, only the internal format changes. And if the conversion fails, the .old backup is still there.
[edit: 2026] The Ansible implementation of all this: the ssh role .