Created
February 21, 2017 23:37
-
-
Save julie-is-late/259a87a7146393aab5819873a193b88c to your computer and use it in GitHub Desktop.
How to load rsa keys in go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package config | |
import ( | |
"crypto/rand" | |
"crypto/rsa" | |
"crypto/x509" | |
"encoding/pem" | |
"io/ioutil" | |
"github.com/CodeCollaborate/Server/utils" | |
) | |
func rsaConfigSetup(rsaPrivateKeyLocation, rsaPrivateKeyPassword string) (*rsa.PrivateKey, error) { | |
if rsaPrivateKeyLocation == "" { | |
utils.LogWarn("No RSA Key given, generating temp one", nil) | |
return GenRSA(4096) | |
} | |
priv, err := ioutil.ReadFile(rsaPrivateKeyLocation) | |
if err != nil { | |
utils.LogWarn("No RSA private key found, generating temp one", nil) | |
return GenRSA(4096) | |
} | |
privPem, _ := pem.Decode(priv) | |
var privPemBytes []byte | |
if privPem.Type != "RSA PRIVATE KEY" { | |
utils.LogWarn("RSA private key is of the wrong type", utils.LogFields{ | |
"Pem Type": privPem.Type, | |
}) | |
} | |
if rsaPrivateKeyPassword != "" { | |
privPemBytes, err = x509.DecryptPEMBlock(privPem, []byte(rsaPrivateKeyPassword)) | |
} else { | |
privPemBytes = privPem.Bytes | |
} | |
var parsedKey interface{} | |
if parsedKey, err = x509.ParsePKCS1PrivateKey(privPemBytes); err != nil { | |
if parsedKey, err = x509.ParsePKCS8PrivateKey(privPemBytes); err != nil { // note this returns type `interface{}` | |
utils.LogError("Unable to parse RSA private key, generating a temp one", err, utils.LogFields{}) | |
return GenRSA(4096) | |
} | |
} | |
var privateKey *rsa.PrivateKey | |
var ok bool | |
privateKey, ok = parsedKey.(*rsa.PrivateKey) | |
if !ok { | |
utils.LogError("Unable to parse RSA private key, generating a temp one", err, utils.LogFields{}) | |
return GenRSA(4096) | |
} | |
pub, err := ioutil.ReadFile(rsaPublicKeyLocation) | |
if err != nil { | |
utils.LogWarn("No RSA public key found, generating temp one", nil) | |
return GenRSA(4096) | |
} | |
pubPem, _ := pem.Decode(pub) | |
if pubPem == nil { | |
utils.LogError("Use `ssh-keygen -f id_rsa.pub -e -m pem > id_rsa.pem` to generate the pem encoding of your RSA public key", | |
errors.New("rsa public key not in pem format"), utils.LogFields{ | |
"Public key location": rsaPublicKeyLocation, | |
}) | |
return GenRSA(4096) | |
} | |
if pubPem.Type != "RSA PUBLIC KEY" { | |
utils.LogWarn("RSA public key is of the wrong type", utils.LogFields{ | |
"Pem Type": pubPem.Type, | |
}) | |
return GenRSA(4096) | |
} | |
if parsedKey, err = x509.ParsePKIXPublicKey(pubPem.Bytes); err != nil { | |
utils.LogError("Unable to parse RSA public key, generating a temp one", err, utils.LogFields{}) | |
return GenRSA(4096) | |
} | |
var pubKey *rsa.PublicKey | |
if pubKey, ok = parsedKey.(*rsa.PublicKey); !ok { | |
utils.LogError("Unable to parse RSA public key, generating a temp one", err, utils.LogFields{}) | |
return GenRSA(4096) | |
} | |
privateKey.PublicKey = pubKey | |
return privateKey, nil | |
} | |
// GenRSA returns a new RSA key of bits length | |
func GenRSA(bits int) (*rsa.PrivateKey, error) { | |
key, err := rsa.GenerateKey(rand.Reader, bits) | |
utils.LogFatal("Failed to generate signing key", err, nil) | |
return key, err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you want to generate a key pair for this with openssl, use the old
genrsa
subcommand, for example:Do not use the new
genpkey
subcommand, for example:While both command generates RSA key pair, the key file format is different.
openssl genrsa
generates private key as pkcs#1 block, which formats like this:openssl genpkey
generates private key as pkcs#8 block, which formats like this:The function x509.DecryptPEMBlock only works with pkcs#1. If you provide it with a pkcs#8 block, it would give you an error: "x509: no DEK-Info header in block".
As specified in #8860, the core library has no real plan to support pkcs#8 in the near future. If you want to work with it, you'll have better luck with 3rd party library like github.com/youmark/pkcs8 (Documentation).