Fun With Public Keys

I just spent a long time diagnosing an RSA public key exchange problem. Google was of very little help so hopefully this article will get picked up save someone else the trouble in the future.

The problem is this an RSA public key PEM or DER generated by Ruby’s OpenSSL::PKey::RSA are unreadable by OpenSSL, Bouncy Castle and probably other crypto tools. For example, if you try to load a public key PEM file generated by OpenSSL::PKey::RSA with the openssl command you get the following error

$  openssl rsa -text -pubin < my_pub_key.pem
unable to load Public Key
16879:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:647:Expecting: PUBLIC KEY

and if you try to load a DER generated by OpenSSL::PKey::RSA you get this error

$  openssl rsa -text -pubin -inform DER < my_pub_key.cer
unable to load Public Key
16880:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1294:
16880:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:380:Type=X509_ALGOR
16880:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:749:Field=algor, Type=X509_PUBKEY

The actual issue is that Ruby’s OpenSSL::PKey::RSA#to_pem and #to_der generate a PKCS#1 public key format while the openssl rsa command only works PKCS#8 formatted public keys. Both of the forms are grammars in the dreaded ASN.1 binary format which completely obscures the differences between them. Both formats encode the exact same information but the PCKS#8 style does it in a more complicated way.

I have not found a good solution to this problem. There does not seem to be any way to make OpenSSL::PKey::RSA#to_pem generate anything other than a PKCS#1 style key. I suspect that OpenSSL is able to handle PKCS#1 public keys but there does not seem to be any way to get the openssl command to do so. Similarly, it seems from Bouncy Castle’s API docs that you should be able to coerce it into accepting PKCS#1 public keys does not do so by default.

Fortunately, OpenSSL::PKey::RSA#new works just fine if handed a PKCS#8 PEM. That has allowed me to work around this issue by using the openssl command to generate the PKCS#8 style PEM files (both private and public using openssl genrsa and openssl rsa -pubout respectively) and then just reading/serving those files as needed. It is not great but it does work.

Comments 3

  1. Ben Curren wrote:

    I wanted to say thanks for the blog post. As you suspected, google pointed me to your blog and it was just what we needed. Thanks!

    Posted 05 Nov 2009 at 12:01 pm
  2. Johne wrote:

    Thanks for this…

    Posted 06 May 2012 at 9:09 am
  3. Dave wrote:

    This is exactly the answer I’ve been digging for. Thank you.

    Posted 13 Jun 2012 at 1:33 pm

Trackbacks & Pingbacks 1

  1. From Résumé partiel des DC18 CTF Quals | Segmentation fault on 24 May 2010 at 1:29 pm

    […] de lire la clé avec cet outil, donc. Un peu de recherche Google, et je trouve quelqu’un qui a eu le même problème : The problem is this an RSA public key PEM or DER generated by […]