I'm trying to get an object of rsa.PublicKey and I made these steps:
----BEGIN RSA PUBLIC KEY----
....
----END RSA PUBLIC KEY----
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
)
func main() {
key, err := ioutil.ReadFile("./new_public.pem")
if err != nil {
fmt.Println(err.Error())
}
block, _ := pem.Decode([]byte(key))
if block == nil {
fmt.Println("unable to decode publicKey to request")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic("failed to parse RSA encoded public key" + err.Error())
}
switch pub := pub.(type) {
case *rsa.PublicKey:
fmt.Println("pub is of type RSA:", pub)
default:
panic("error")
}
}
After this, when I try to x509.ParsePKIXPublicKey(block.Bytes)
I get an error:
panic: failed to parse RSA encoded public keyasn1:
structure error: tags don't match (16 vs {class:0 tag:2 length:129 isCompound:false})
{
optional:false
explicit:false
application:false
private:false
defaultValue:<nil> tag:<nil>
stringType:0
timeType:0
set:false
omitEmpty:false
} AlgorithmIdentifier @3
So, I read some blogs and documentations about DER and PEM formats, and they are differents ways to encode an certificate, basicaly one use base64 and other is just bytes.
In x509's package of Golang, the x509.ParsePKIXPublicKey says:
ParsePKIXPublicKey parses a DER-encoded public key. These values are typically found in PEM blocks with "BEGIN PUBLIC KEY"
And, in the example of this function use the pem.Decode(). I'm very confused about this because this should use pem.Decode
or something like der.Decode()
?
Also, what's the real difference between x509.ParsePKCS1PublicKey()
and x509.ParsePKIXPublicKey()
? Both do the same job to get a rsa.PublicKey ?
The issue here is understanding the difference between x509.ParsePKCS1PublicKey
(PKCS#1) and x509.ParsePKIXPublicKey
(PKCS#8).
Usually when the PEM header has the type as RSA PUBLIC KEY
, it is referring to a PKCS#1 encoded RSA public key, which is defined in RFC 8017 (PKCS#1) as:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
You haven't actually provided the body of your public key (it would be safe to do so), but it is a fair assumption that, if decoding the key using x509.ParsePKIXPublicKey
failed, your key is likely in the above format (x509.ParsePKIXPublicKey
uses PKCS#8 encoding).
If this is the case, you should be able to get an rsa.PublicKey
from the file using the following code (don't forget to add the error handling):
rawPem, _ := ioutil.ReadFile("./public.key")
pemBlock, _ := pem.Decode(rawPem)
publicKey, _ := x509.ParsePKCS1PublicKey(pemBlock.Bytes)
If this doesn't solve your problem, try pasting the key you have into this site to see what ASN.1 structure it uses. For reference, the key I used to test this is included here:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEApW1W9dnfdFF7FHrq6HPveR/9T+nM70yO7QOGytR0j/chMBJcJBjG
hJOuKPFbkVyS+BE/4M8CojLgvz4ex82Re0sFa5TqnoWvuP5P4vktR6M5W53sTW3y
gUnfF/oHcEmARQ1xKZdgVnlIfrdbpjecPyLi1Ng4HmhEfCFUOW64koxpb4XeH5O5
q+vc/731ExVOYBU8Sl6kPdjpJuVjS3DHKAVgfVEhscXd3JDjDuMDT3w1IYNb5c2s
wHE55q4Jnc1cr42jdynnkXzmuOGo2C6yD95kbBDLp7wSiBxaMA8gbRkzWJ99T+6l
KsKG2zfndMF3jZW1v1wWiEbYRN07qbN0NQIDAQAB
-----END RSA PUBLIC KEY-----
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With