I have lost access to my ~/.ssh/id_dsa file (OpenSSH private key file in DSA algorithm), due to forgetting the passphrase.

But, originally, I have had it imported into gpg-agent and protected it with a gpg-agent passphrase, which I do know. And the private key is still working fine under gpg-agent even now, although I now desire to reconstruct the OpenSSH private key file using what is stored in gpg-agent.

Using gpg-connect-agent tool, with the following sequence of commands, I think am able to extract the private key (in hex/ascii format), though I don't know how to reconstruct it to the original OpenSSH private key file format:

  1. Start gpg-connect-agent with --hex option.
  2. In the > prompt, get the hex ID of the key using keyinfo --ssh-list command (to be precise it's the third field that gives the hex ID of the key).
  3. In the > prompt, execute keywrap_key --export.
  4. In the > prompt, execute export_key <enter hex ID from step 2> or export_key --openpgp <enter hex ID from step 2>.

Now, after prompting for the passphrase, receiving it and confirming it, gpg-connect-agent tool displays a few dozen lines of hex & ascii codes, which I highly suspect to be my original imported ssh private key.

Then, it displays OK, surely implying the operation was successful.

Assuming what it displayed is indeed my ssh private key (as per "help export_key", what was dumped on the screen is aeswrap-128 encrypted version of the key; most likely encrypted with my known gpg-agent passphrase), some help on how to convert that info into traditional ssh private key format would be much appreciated (a perl/python/shell/C program to do it would be a bonus!).


Hoping to help, but I'm a bit out of topic, because I stumbled upon this question while having an unrelated issue. During a gpg 2.1.6->2.1.10 upgrade I encountered a Ed25519 private key parsing issue: https://bugs.gnupg.org/gnupg/issue2096. The script I wrote scratches my own itch, it can dump an unprotected S-expression key which I was able to hexedit and re-encrypt.

So, regarding this question, I wrote a Python script (https://gist.github.com/zougloub/3058d56857ba400b7ec3) that uses gpg-agent to extract the unprotected S-expression SSH private key, by retrieving the libassuan-escaped keywrap key, the encrypted key, and decrypting it (using libgcrypt). It doesn't completely answer your question, as it doesn't dump the data in SSH format.

Hopefully you can get that further, as the data is at least in a parsable state now.

Further pointers:

I was curious to see if I could do the extra mile, but I've already lost too much time geeking around... someone sane would have just regenerated an SSH key :D


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.