Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save shakahl/2f1e42d688e998600e55647bd0a785d8 to your computer and use it in GitHub Desktop.
Save shakahl/2f1e42d688e998600e55647bd0a785d8 to your computer and use it in GitHub Desktop.

So you deleted a private key file and have no backup?

It happened to me in my first IT job. I was told to rm a couple of outdated keyfiles. Of course they weren't named in a human readable manner. And of course I tab-completed to the wrong directory...

AAAAAAAAAAAAHHHH!!!

Of course, there was no such thing as "undelete" on the linux-box in question.

thinking...

rm only deletes the pointer to the file. It doesn't overwrite it.

thinking more...

"Everything is a file". Can I grep the disk for the key?

It turned out I could. And I was lucky enough to still have a copy of the public key.

Below solution uses sed, though, to save you the pain of hours-long manual-editing of files I needed to do back then. I had started from grepping with context before and after, then did lots of copy-pasting. You do not want to do that.

  1. First things first: Stop all processes that write to the partition in question. Otherwise your still existing key may get overwritten.

  2. find another partition with enough space to write to.

  3. now if /dev/sda1 is the partition where you deleted the key...

    #> sed -n '/-----BEGIN RSA PRIVATE KEY-----/,/-----END RSA PRIVATE KEY-----/p' /dev/sda > /path/to/some/other/partition/rescue.txt
    

    The "some other partition"-part is important. You don't want to overwrite your key. And you don't want to create an endless loop filling the whole partition with the keys you found and wrote into rescue.txt where you found them again. Ok, now you have ALL the keys from the partition in one file.

  4. Divide the big file into multiple files, each containing one key:

    #> csplit -f key rescue.txt '/-----END RSA PRIVATE KEY-----/' '{*}'
    

    This will procude a number of files named "key00", "key01" and so on.

  5. If you still have your public key, like I did, you're in luck:
    Every private key file contains a copy of it's public key. You can extract that, and compare it with the public key you have.

    for i in key*; do diff <(ssh-keygen -y -f $i) <(cut -d' ' -f1-2 iStillHaveIt.pub)&& echo "And the winner is $i"; done |grep winner
    

    The "cut"-command here is necessary, because the public key extracted from the private key will not have a comment.

Doing this on a partition with a few gigabytes will take time, but if your key wasn't overwritten, you'll get the key back.

If you don't have a public key to compare to, you'll have to iterate through all your private keys, compare them to the all the keys you found and if they match delete the key you found from your working directory. If you're lucky there will be exactly one left. Otherwise you'll have to find anotherway to choose the right one...

The technique described above will work for other filetypes as well, as long as you have some start- and stop-markers you can hand to sed.

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