I was looking for a way to encrypt data in R. Hadley Wickham’s secure package looked like it’d do the trick, using my SSH keys. So I set up my vault, and added my key. So far, so good. Then I tried to store some data:
> secure::encrypt("google", key = "abcdasdf", secret = "asdfsad") Error in PKI::PKI.load.key(file = "~/.ssh/id_rsa") : error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib
Hmmmm. It failed to load my private key. No real surprise – it hadn’t asked for my password. Looking at the code, it’s using the PKI package under the hood. The PKI.load.key() function has a password parameter, but the secure package isn’t passing it. And I can’t specify another cert (one without a password) even if I wanted to – the certificate path is hardcoded. Damn.
I don’t want to remove the password from my cert. I’m using it in too many places. Places I value password protection, like GitHub.
So much for using secure.
But inspired by secure, I took a look at using PKI directly. First, I tried loading my public key:
> key_pub <- PKI.load.key(format = "PEM", private = FALSE, file = "~/.ssh/id_rsa.pub") Error in PKI.load.key(format = "PEM", private = FALSE, file = "~/.ssh/id_rsa.pub") : cannot find public RSA key in PEM format
Great. PKI doesn’t understand the format of my public key. Not for the first time, stackexchange came to the rescue. The following commands fixed the problem:
cp ~/.ssh/id_rsa.pub ~/.ssh/id_rsa.pub.old ssh-keygen -f ~/.ssh/id_rsa.pub.old -e -m pem > ~/.ssh/id_rsa.pub
Now for the private key (note that I have RStudio prompt for the password, rather than hardcoding it. That would need a more elegant solution if I were to productionise this code):
> key_prv <- PKI.load.key(format = "PEM", private = TRUE, file = "~/.ssh/id_rsa", password = rstudioapi::askForPassword("Private key password")) Error in PKI.load.key(format = "PEM", private = TRUE, file = "~/.ssh/id_rsa", : error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
Damnit. This took a bit more hunting around to fix. PKI strips out and ignores what looks like some pretty vital information at the top of the cert:
$ head id_rsa -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,....
So I had to convert my private key to a format PKI understands. I eventually tracked down what I needed here:
cp ~/.ssh/id_rsa ~/.ssh/id_rsa.old openssl pkcs8 -topk8 -v2 des3 -in ~/.ssh/id_rsa.old -out ~/.ssh/id_rsa
The old and new keyfiles seem to be compatible, thankfully – replacing the old one doesn’t seem to have caused me any issues (since I used my old password for the new cert).
I’m finally in a position to use the package.