It took me an embarassingly long time to discover how to do this today, so I thought I’d write it down and send it into the ether of the Internet hoping it would help someone else someday.
So I have this great golang server which connects to a remote host over
SSH. Not so bad so far, golang.org/x/crypto/ssh
makes this pretty easy.
The hard part is that the normal tools we use to generate SSH keys are
not compatible with this crypto/ssh library.
My goal was to have a private key, PEM encoded, and encrypted with a
passphrase. This would be loaded by my Go code. Then, I wanted to generate
a public key for that private key that was in that funky authorized_keys
SSH form of key-type key-value key-comment
.
Using ssh-keygen gets you a PEM-encoded private key and a properly encoded public key, but when you try to load the private key into the Go library, it chokes on the passphrase. The trick is that several important headers are missing which tell the Go library that it’s encrypted.
# To generate the private key, run the following:
$ openssl genrsa -des3 -out private.pem 4096
Now you have your private key. Now you need to generate the public key.
# To generate the *public* key from your private key, run the following:
$ openssl rsa -in private.pem -outform PEM -pubout -out public.pem
Now you have a PEM format for your public key. Nice! This can’t be used
with SSH’s authorized_keys
file though, so we’ll have to do one more
conversion:
# To generate the ssh-rsa public key format, run the following:
$ ssh-keygen -f public.pem -i -mPKCS8 > id_rsa.pub
Now you have a public key in the format OpenSSH expects.
private.pem
- your encrypted, PEM-encoded private keyid_rsa.pub
- your OpenSSH-compatible public keyThat seems to do the trick for me, and SSH connections are working great between my Go service and my servers.