Decode a public key from ASN1 or PEM

3,197 views
Skip to first unread message

Nick

unread,
Jun 5, 2013, 2:05:02 PM6/5/13
to golan...@googlegroups.com
Hello,

I've got a key (encoded with ASN1 and PEM so I can choose)  and I want to create a new rsa public key from it. However, there's only a function to create a private key with a public key, but not for a public key alone.
Are there any methods to create a RSA public key from ASN1 or PEM?

Thanks,
Nick

Jeff Mitchell

unread,
Jun 5, 2013, 2:23:54 PM6/5/13
to Nick, golan...@googlegroups.com
Hi,

I haven't done exactly this, but I can get you 95% of the way: look at the Decode method in encoding/pem to get a Block representing the key; then pass the Block's Bytes member into the ParsePKIXPublicKey function from crypto/x509. If all goes well, based on my knowledge of the code (and another quick look at the sources), you should be able to type-assert the returned interface{} to an rsa.PublicKey.

--Jeff

agl

unread,
Jun 5, 2013, 3:28:09 PM6/5/13
to golan...@googlegroups.com
On Wednesday, June 5, 2013 2:05:02 PM UTC-4, Nick wrote:
I've got a key (encoded with ASN1 and PEM so I can choose)  and I want to create a new rsa public key from it. However, there's only a function to create a private key with a public key, but not for a public key alone.
Are there any methods to create a RSA public key from ASN1 or PEM?

Do be clear, you have an RSA private key in hand? What's the first line of the PEM? (The line that starts -----BEGIN ...)

If you get the DER bytes (either by loading them directly, or by using encoding/pem, as Jeff suggests) you you should be able to pass them to  http://golang.org/pkg/crypto/x509/#ParsePKCS1PrivateKey and then pass the RSA key to http://golang.org/pkg/crypto/x509/#MarshalPKIXPublicKey. However, there are a few key formats so that might not be quite what you want.


Cheers

AGL

Jeff Mitchell

unread,
Jun 5, 2013, 3:37:00 PM6/5/13
to agl, golan...@googlegroups.com
Also, unless I misunderstand the API, doing this requires him to be
loading a private key, and then pulling the public key out of
that...which is not what the OG said was available to him (a public key).

--Jeff

agl

unread,
Jun 5, 2013, 3:42:27 PM6/5/13
to golan...@googlegroups.com, agl
On Wednesday, June 5, 2013 3:37:00 PM UTC-4, Jeff Mitchell wrote:
Also, unless I misunderstand the API, doing this requires him to be
loading a private key, and then pulling the public key out of
that...which is not what the OG said was available to him (a public key).

Yes, that's assuming that he has a private key and wants to write out the public key of it. I got that from "Are there any methods to create a RSA public key from ASN1 or PEM?" Maybe I completely misunderstood.


Cheers

AGL

Jeff Mitchell

unread,
Jun 5, 2013, 3:48:42 PM6/5/13
to agl, golan...@googlegroups.com
agl wrote:
> Yes, that's assuming that he has a private key and wants to write out
> the public key of it. I got that from "Are there any methods to create
> a RSA public key from ASN1 or PEM?" Maybe I completely misunderstood.

Ah, heh -- different readings then...I took PEM to mean "DER-encoded public key in a base64-encoded .pem file"*...but I think this goes to show that "PEM" alone isn't sufficient to know true intent.

--Jeff

* For instance, I have some .pem files that contain only a -----BEGIN PUBLIC KEY----- / -----END PUBLIC KEY----- block

Nick

unread,
Jun 5, 2013, 3:52:41 PM6/5/13
to golan...@googlegroups.com, agl
Yes, I meant to load a public key that is stored in a PEM file and ASN1 encoded that I don't have the corresponding private key so that I could send an encrypted message. 

I don't understand though why this is so difficult; sending a message without the private key should be a normal thing to do?

Jeff Mitchell

unread,
Jun 5, 2013, 4:08:16 PM6/5/13
to Nick, golan...@googlegroups.com, agl
Nick wrote:
> Yes, I meant to load a public key that is stored in a PEM file and ASN1
> encoded that I *don't* have the corresponding private key so that I
> could send an encrypted message.
>
> I don't understand though why this is so difficult; sending a message
> without the private key should be a normal thing to do?

"Difficulty" might be a matter of expectations. Passing the file's bytes
into a parser (the encoding/pem call) and then extracting the various
parameters necessary to then actually make use of it (the crypto/x509
call) doesn't seem unreasonable at all.

Maybe a high-level library would abstract all of that into a single call
taking in a file path, but such a library would necessarily be more
special-purpose than what the standard library provides. If such a
library doesn't exist (I don't know), please feel free to make it and
announce it here...or you could ask the language devs whether they'd
accept a merge request to the standard library that contains such a
convenience function.

--Jeff

agl

unread,
Jun 5, 2013, 4:20:49 PM6/5/13
to golan...@googlegroups.com, agl
On Wednesday, June 5, 2013 3:52:41 PM UTC-4, Nick wrote:
Yes, I meant to load a public key that is stored in a PEM file and ASN1 encoded that I don't have the corresponding private key so that I could send an encrypted message. 

I don't understand though why this is so difficult; sending a message without the private key should be a normal thing to do?

The code would be something like:

import (
   "errors"
   "encoding/pem"
   "crypto/x509"
   "io/ioutil"
   "crypto/rsa"
)

..

  pemBytes, err := ioutil.ReadFile("filename.pem")
  if err != nil {
    return err
  }
  block, _ := pem.Decode(pemBytes)
  if block == nil {
    return errors.New("no PEM block found")
  }
  key, err := x509.ParsePKIXPublicKey(block.Bytes)
  if err != nil {
    return err
  }
  rsaPub, ok := key.(*rsa.PublicKey)
  if !ok {
    return errors.New("not an RSA public key")
  }

There is higher level code (e.g. [1]), but crypto/x509 isn't it.


Cheers

AGL

Reply all
Reply to author
Forward
0 new messages