What causes "Neither PUB key nor PRIV key:: nested asn1 error" when building a public key in ruby?
Asked Answered
N

10

50

When building a public key using the OpenSSL::PKey::RSA module by passing it a .pem file, what is the cause for a response:

OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key:: nested asn1 error
from /Users/Matt/projects/placepop/lib/apn.rb:48:in `initialize'
from /Users/Matt/projects/placepop/lib/apn.rb:48:in `new'
from /Users/Matt/projects/placepop/lib/apn.rb:48:in `open'
from (irb):1

Here is the source:

cert = File.join(rails_root, 'config', 'apns', 'sandbox-cert.pem')
APN_CONFIG = { :delivery => { 
                              :host => 'gateway.sandbox.push.apple.com', 
                              :cert => cert,
                              :passphrase => "",
                              :port => 2195 },
               :feedback => {  
                              :host => 'feedback.sandbox.push.apple.com',
                              :port => 2196,
                              :passphrase => "",
                              :cert => cert} }


options = APN_CONFIG[:delivery].merge(options)
cert = File.read(options[:cert])
ctx = OpenSSL::SSL::SSLContext.new
ctx.key = OpenSSL::PKey::RSA.new(cert, options[:passphrase])
ctx.cert = OpenSSL::X509::Certificate.new(cert)

sock = TCPSocket.new(options[:host], options[:port])
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
ssl.sync = true
ssl.connect
Nonfeasance answered 19/2, 2010 at 1:58 Comment(0)
B
18

A pem file is not a public key, it is a base64-encoded X509 certificate that contains, among its many fields, a public key. I don't know Ruby, or the OpenSSL ruby module, but I would look for some function that reads in PEM files and outputs an X509 certificate, then another function to extract the public key from the certificate.

Baggy answered 20/2, 2010 at 0:50 Comment(5)
You're correct. The problem was from the way that the pem file was exported from the certificate. The private key was not included.Nonfeasance
I'm having the same problem. What exactly did you do wrong when exporting the certificate? My .pem file contains my private key at the bottom of the file.Ghassan
I am having the same issue...i pass only my private key !Stinkwood
This solved my problem: https://mcmap.net/q/355448/-rails-can-39-t-read-certificate-information-from-environment-due-to-nested-asn1-error. Store the PEM contents as a single line (using \n) in an ENV variable, and then make sure to use the .gsub suggestion in the link.Sulfide
My (silly) problem was, even though I was feeding it the private key, there was whitespace on the left of the lines of the private key, because it had been indented. Left-justifying every line of the key string got rid of this error.Chloris
E
40

If you are using dotenv for instance, you have to surround the value with " and have \n for newlines.

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIICW  ... UcuUtU0eIl\n-----END RSA PRIVATE KEY-----"
Egoism answered 12/4, 2017 at 22:47 Comment(2)
My problem is exactly this. Thank you!Wonky
also wrapped the key in " and it works for me now, thank you!Big
B
39

I've got the same problem and it had a different cause. Now guess what :)

...

The damn password was wrong :( Searched 3 days for that "solution". Could have been a "Sorry dude, that's the wrong password!" instead of "nested asn1 error" imho but anyways, maybe this will help somebody.

Blower answered 22/10, 2012 at 12:31 Comment(4)
Someone should poke upstream with sturdy stick about this too... escapesTiloine
I confirm, had the same issue and a wrong password was causing it. Thanks to your post, I was able to fix it. The error message is definitely not accurate.Katzman
@Blower as of 2018 I can't thank you enough haha thinking that the pw had typos was the last thing I thought about when checking some code that wasn't working, that error message couldn't be more uselessSufficiency
You da man! I don't know I messed up the password. But recreating the keys fixed this. Many thanks!Sullins
B
18

A pem file is not a public key, it is a base64-encoded X509 certificate that contains, among its many fields, a public key. I don't know Ruby, or the OpenSSL ruby module, but I would look for some function that reads in PEM files and outputs an X509 certificate, then another function to extract the public key from the certificate.

Baggy answered 20/2, 2010 at 0:50 Comment(5)
You're correct. The problem was from the way that the pem file was exported from the certificate. The private key was not included.Nonfeasance
I'm having the same problem. What exactly did you do wrong when exporting the certificate? My .pem file contains my private key at the bottom of the file.Ghassan
I am having the same issue...i pass only my private key !Stinkwood
This solved my problem: https://mcmap.net/q/355448/-rails-can-39-t-read-certificate-information-from-environment-due-to-nested-asn1-error. Store the PEM contents as a single line (using \n) in an ENV variable, and then make sure to use the .gsub suggestion in the link.Sulfide
My (silly) problem was, even though I was feeding it the private key, there was whitespace on the left of the lines of the private key, because it had been indented. Left-justifying every line of the key string got rid of this error.Chloris
C
5

I had a similar problem too, but for me I wasn't creating a pem file for my id_rsa.pub file in the first place. For me I needed to create a pem file out of my existing public key:

ssh-keygen -f testing_rsa.pub  -e -m pem > pem

Then I copied that OpenSSL string into my test file where it was being used. It looked like this in the end for me.

@pub_key = "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAoxi2V0bSKqAqUtoQHxWkOPnErCS541r6/MOSHmKOd6VSNHoBbnas\nZRQSDUTbffB6C++DbmBCOHmvzYORD0ZWYgyMcgbYJD48Z2fe0nm+WMYN5u8DPnTP\nvf8b/rJBxGF0dsaoFAWlB81tTnKFCxAbCSgfmQt+Vd4qupGZ5gGu9uoKlaPjmYuA\nIxIjUMcu3dov7PQ+PZIvdkM0fiz8YIl8zo+iWWyI2s6/XLoZJ4bYs2YJHZDf6biU\nsZhs8xqh/F6qlcRt3Ta25KMa0TB9zE3HHmqA/EJHFubWFRCrQqpboB0+nwCbmZUl\nhaxA79FRvYtORvFAoncoFD4tq3rGXcUQQwIDAQAB\n-----END RSA PUBLIC KEY-----\n"
.
.
.
OpenSSL::PKey::RSA.new(@pub_key)

After that the method stopped throwing that error.

Casper answered 19/3, 2013 at 22:11 Comment(1)
Thanks! I was exactly in the same case.Brahma
R
5

Make sure your .pem files are in this format.

public_key_file.pem:

-----BEGIN PUBLIC KEY-----

// Your public key goes here

-----END PUBLIC KEY-----

private_key_file.pem:

-----BEGIN RSA PRIVATE KEY-----

// Your private key goes here

-----END RSA PRIVATE KEY-----
Ribera answered 28/3, 2019 at 5:20 Comment(2)
Just adding the link to the LTI 1.3 reference implementation which was giving me this error until I followed your advice to leave in the BEGIN and END comments: lti-ri.imsglobal.orgVacuity
I can confirm this solution in Fluentd, a RUBY-based app. The private key must contain a RSA string in the header.Important
G
3

My problem was that OpenSSL::PKey::RSA.new() wants the file contents and not the file path. Thus, using something like this worked:

OpenSSL::PKey::RSA.new(File.read "./spec/support/keys/server.key")

The OP was already doing this, but hopefully this will help someone. Because it assumes it's file contents and not a file path, even if you supply an invalid path you won't be warned.

Gamut answered 10/7, 2014 at 5:25 Comment(0)
S
2

I got this error while using dotenv with rails. The issue was not with respect to dotenv gem. It was assigning correct value as confirmed by printing ENV['PRIVATE_KEY']

Issue occurred because i was loading this value in YAML file with ERB processing and that led to removal of \n character hence making the value invalid

The workaround that i found was to use ENV['PRIVATE_KEY'] directly and not via YAML

Saguache answered 21/2, 2020 at 10:44 Comment(0)
M
1

I am using Webrick in my tests and trying to instantiate my private key with the wrong class led me to that error message:

    SSLCertificate: OpenSSL::PKey::RSA.new(File.open(MOCK_CERT).read),

But this worked:

    SSLCertificate: OpenSSL::X509::Certificate.new(File.open(MOCK_CERT).read),

Facepalm

Mangan answered 29/10, 2019 at 13:39 Comment(0)
M
1

if none of the above answers worked, it might be because of an incorrect algorithm. newer public keys are made using ECDSA algorithm instead of RSA, so OpenSSL::PKey::EC class should be used instead.

You can verify the key's algorithm using this online tool. it detects the algorithm and provides useful information about the key.

Mattress answered 7/9, 2020 at 7:48 Comment(0)
F
0

In my case the function expected a private key while there was a certificate stored in some variable. Exchanging the input with a private key fixed the error.

Fanion answered 18/10, 2017 at 19:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.