Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read an RSA key from file

I need to read in an RSA private key from a file to sign a JWT. I have found some examples on how to save a generated RSA key to disk but nothing showing how to build a key struct based on a pre-generated key from a file.

The key is generated like this:

openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt

Example key:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClHYNDPVSF‌​FmWF 
oKGTqd/n7Dt2+tGXh97KJjVLAqCBZZHlQJ534v2OzFjTgzuMNehD9Y6HnkYF‌​dkRb 
QzYi2YDROOzRl1bhyyWPA35OGf50r7LiNvSvNPNtswsCuK7ywOcH0yEMKSiW‌​4q5R 
GKYi42w961EcTQQPrfihavY+c2FYPv4+pXymzaIz9hGBPLHwaHq/QTAyHxPC‌​fkOo 
s/x3mxUVd7Ni2bz1VJGlyqcNEeU88wTAYMmv8oQ3y2NfKExtYn+W6TCDiq/+‌​ZkOp 
wacuAU0J7tCNgcXvkq39KH5uza2uSiTniye6uhlkvYWD3s9riIIiekTEiHk/‌​kkc6 
jMg8HN/7AgMBAAECggEBAJ12u8vQHV6esUrymaTdCG+BVmRtZpyA ... 
-----END RSA PRIVATE KEY-----
like image 823
Ed S. Avatar asked May 28 '17 18:05

Ed S.


People also ask

How do you read a private key?

Click Domains > your domain > SSL/TLS Certificates. You'll see a page like the one shown below. The key icon with the message “Private key part supplied” means there is a matching key on your server. To get it in plain text format, click the name and scroll down the page until you see the key code.

How do I convert my RSA key?

Open PuTTYgen, choose Key > SSH-2 RSA key, and select RSA in the lower left corner. Import the private key in OpenSSH format to PuTTYgen. Choose Conversions > Import key, select the private key in OpenSSH format, and open it. Choose Conversions > Export OpenSSH key, name and save the file.

What format is RSA key in?

PEM. This format can contain private keys (RSA or DSA), public keys (RSA or DSA) and X. 509 certificates. It is the default format for OpenSSL.


2 Answers

A combination of pem.Decode and x509.ParsePKCS1PrivateKey should do the trick:

package main

import (
    "crypto/x509"
    "encoding/pem"
    "fmt"
)

func main() {
    pemString := `-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDLets8+7M+iAQAqN/5BVyCIjhTQ4cmXulL+gm3v0oGMWzLupUS
v8KPA+Tp7dgC/DZPfMLaNH1obBBhJ9DhS6RdS3AS3kzeFrdu8zFHLWF53DUBhS92
5dCAEuJpDnNizdEhxTfoHrhuCmz8l2nt1pe5eUK2XWgd08Uc93h5ij098wIDAQAB
AoGAHLaZeWGLSaen6O/rqxg2laZ+jEFbMO7zvOTruiIkL/uJfrY1kw+8RLIn+1q0
wLcWcuEIHgKKL9IP/aXAtAoYh1FBvRPLkovF1NZB0Je/+CSGka6wvc3TGdvppZJe
rKNcUvuOYLxkmLy4g9zuY5qrxFyhtIn2qZzXEtLaVOHzPQECQQDvN0mSajpU7dTB
w4jwx7IRXGSSx65c+AsHSc1Rj++9qtPC6WsFgAfFN2CEmqhMbEUVGPv/aPjdyWk9
pyLE9xR/AkEA2cGwyIunijE5v2rlZAD7C4vRgdcMyCf3uuPcgzFtsR6ZhyQSgLZ8
YRPuvwm4cdPJMmO3YwBfxT6XGuSc2k8MjQJBAI0+b8prvpV2+DCQa8L/pjxp+VhR
Xrq2GozrHrgR7NRokTB88hwFRJFF6U9iogy9wOx8HA7qxEbwLZuhm/4AhbECQC2a
d8h4Ht09E+f3nhTEc87mODkl7WJZpHL6V2sORfeq/eIkds+H6CJ4hy5w/bSw8tjf
sz9Di8sGIaUbLZI2rd0CQQCzlVwEtRtoNCyMJTTrkgUuNufLP19RZ5FpyXxBO5/u
QastnN77KfUwdj3SJt44U/uh1jAIv4oSLBr8HYUkbnI8
-----END RSA PRIVATE KEY-----`

    block, _ := pem.Decode([]byte(pemString))
    key, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
    fmt.Println(key.N)
}

If what you are sitting on is a PKCS#8 encoded key, instead you would do something like the following:

func main() {
    pemString := `-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKhPSTDs4cpKfnMc
p86fCkpnuER7bGc+mGkhkw6bE+BnROfrDCFBSjrENLS5JcsenANQ1kYGt9iVW2fd
ZAWUdDoj+t7g6+fDpzY1BzPSUls421Dmu7joDPY8jSdMzFCeg7Lyj0I36bJJ7ooD
VPW6Q0XQcb8FfBiFPAKuY4elj/YDAgMBAAECgYBo2GMWmCmbM0aL/KjH/KiTawMN
nfkMY6DbtK9/5LjADHSPKAt5V8ueygSvI7rYSiwToLKqEptJztiO3gnls/GmFzj1
V/QEvFs6Ux3b0hD2SGpGy1m6NWWoAFlMISRkNiAxo+AMdCi4I1hpk4+bHr9VO2Bv
V0zKFxmgn1R8qAR+4QJBANqKxJ/qJ5+lyPuDYf5s+gkZWjCLTC7hPxIJQByDLICw
iEnqcn0n9Gslk5ngJIGQcKBXIp5i0jWSdKN/hLxwgHECQQDFKGmo8niLzEJ5sa1r
spww8Hc2aJM0pBwceshT8ZgVPnpgmITU1ENsKpJ+y1RTjZD6N0aj9gS9UB/UXdTr
HBezAkEAqkDRTYOtusH9AXQpM3zSjaQijw72Gs9/wx1RxOSsFtVwV6U97CLkV1S+
2HG1/vn3w/IeFiYGfZXLKFR/pA5BAQJAbFeu6IaGM9yFUzaOZDZ8mnAqMp349t6Q
DB5045xJxLLWsSpfJE2Y12H1qvO1XUzYNIgXq5ZQOHBFbYA6txBy/QJBAKDRQN47
6YClq9652X+1lYIY/h8MxKiXpVZVncXRgY6pbj4pmWEAM88jra9Wq6R77ocyECzi
XCqi18A/sl6ymWc=
-----END PRIVATE KEY-----`

    block, _ := pem.Decode([]byte(pemString))
    parseResult, _ := x509.ParsePKCS8PrivateKey(block.Bytes)
    key := parseResult.(*rsa.PrivateKey)
    fmt.Println(key.N)
}
like image 130
fuglede Avatar answered Oct 01 '22 18:10

fuglede


There is a helpful function ssh.ParseRawPrivateKey which already implements some of the required logic. I suggest building upon it, especially if your key is used as a SSH key, which in my case it is.

import (
    "os"
    "crypto/rsa"
    "golang.org/x/crypto/ssh"
    "io/ioutil"
)

func mustNot(err error) {
    if err != nil {
        panic(err)
    }
}

func loadRsaPrivateKey() *rsa.PrivateKey {
    bytes, err := ioutil.ReadFile(os.Getenv("HOME") + "/.ssh/id_rsa")
    mustNot(err)
    key, err := ssh.ParseRawPrivateKey(bytes)
    mustNot(err)
    return key.(*rsa.PrivateKey)
}
like image 38
user7610 Avatar answered Oct 01 '22 20:10

user7610