Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@fredreichbier
Last active March 10, 2024 09:47
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fredreichbier/4399625 to your computer and use it in GitHub Desktop.
Save fredreichbier/4399625 to your computer and use it in GitHub Desktop.
How to extract your private ssh key from gpg-agent

How to extract a SSH private key from gpg-agent

Problem: Lost private key file ~/.ssh/id_rsa, but could connect to remote hosts via pubkey auth anyway: gpg-agent cached the private key. How to get the private key?

Solution: Use gpg-protect-tool to get the key (you need to know the passphrase of course):

gpgsm --call-protect-tool --p12-export ~/.gnupg/private-keys-v1.d/your-keyfile.key >key.p12

Now you have a PKCS12 file and you can extract the private key like this:

openssl pkcs12 -in key.p12 -out privkey.pem

And there is your extracted private key.

@rafasc
Copy link

rafasc commented Mar 22, 2018

is there an updated method to do this? --p12-export is no longer supported.

@flowthentic
Copy link

Find a keygrip of desired private key
gpg --list-secret-keys --with-keygrip

Import it into a new temporary gpgsm keyring
gpgsm --gen-key -o /tmp/keyring
#> 2 #select existing key
#> #keygrip_id
#> 3 #key purpose encryption, this is probably irrelevant
#> C=dummy, ST=dummy, L=dummy, O=dummy, OU=dummy, CN=dummy #Enter dummy X.509 subject name
#> nonexistent@dummy.com #email as well
The rest of the options are optional so just Enter through them, confirm the information, and enter the decryption password of key selected.

Now convert the key to pkcs12 format
gpgsm -o /tmp/key.p12 --export-secret-key-p12 '&keygrip_id'
Enter again the encryption password as before to decrypt it. Then enter new password which should be used for .p12 file. If your /tmp folder resides on RAM like mine, you can leave it blank as it will be safely removed after reboot.

Now convert it to ssh friendly format, which requires stripping first 4 output lines, so that it starts with ---BEGIN PRIVATE KEY---.
openssl pkcs12 -in /tmp/key.p12 -nodes -nocerts | tail -n +5 > /tmp/sshkey

There you have sshkey ready to use by ssh client. Hope this helps.

@rafasc
Copy link

rafasc commented Jun 11, 2020

gpg --list-secret-keys --with-keygrip will not list keys cached by the gpg-agent that ended up there from an ssh-add. I.e. Some of the ones found in gpg-connect-agent <<<"keyinfo --ssh-list" will not work with this method.

Also, if the key added to the agent has a comment field, gpgsm completely chokes on it. I mentioned on IRC and dkg reported in my behalf: https://dev.gnupg.org/T4892

Let's see what comes out of it.

@hanyuwei70
Copy link

have same problem exporting my ed25519 key. wait for it.

@ansemjo
Copy link

ansemjo commented May 12, 2021

While this is blocked on support in an up-to-date gpgsm you can just use an old version .. for example Debian 8 "Jessie" has gpgsm (GnuPG) 2.0.26, which still has --p12-export. The quickest way for me to use it was in a container, something like this:

$ docker run --rm -it -v ~/.gnupg:/gnupg debian:8
root@f12e2268d754:/# apt update && apt install -y gpgsm
[...]
root@f12e2268d754:/# gpgsm --call-protect-tool --p12-export /gnupg/private-keys-v1.d/KEYGRIP.key > /gnupg/lostkey.p12
root@f12e2268d754:/# exit
$ openssl pkcs12 -in ~/.gnupg/lostkey.p12 -out ~/privkey.pem

@hanyuwei70
Copy link

While this is blocked on support in an up-to-date gpgsm you can just use an old version .. for example Debian 8 "Jessie" has gpgsm (GnuPG) 2.0.26, which still has --p12-export. The quickest way for me to use it was in a container, something like this:

$ docker run --rm -it -v ~/.gnupg:/gnupg debian:8
root@f12e2268d754:/# apt update && apt install -y gpgsm
[...]
root@f12e2268d754:/# gpgsm --call-protect-tool --p12-export /gnupg/private-keys-v1.d/KEYGRIP.key > /gnupg/lostkey.p12
root@f12e2268d754:/# exit
$ openssl pkcs12 -in ~/.gnupg/lostkey.p12 -out ~/privkey.pem

tried, but it didn't work on my ed25519 key, complaing about "error converting key parameters". seems doesn't support ed25519.
But I have decrypted my key and get q,d two integers, finding way to construct final openssh keys.

@hanyuwei70
Copy link

nvm. I have managed to recover my private key by decrypt original key and using cryptography Python library.
if you decrypted your key, there is a d section which is 32 bytes long. Use that in cryptography library to reconstruct your OpenSSH key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment