47

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
Matthew
  • 5,435
  • 6
  • 25
  • 29

10 Answers10

38

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.

2called-chaos
  • 3,018
  • 3
  • 21
  • 29
  • 2
    Someone should poke upstream with sturdy stick about this too... *escapes* – Smar Apr 15 '15 at 13:04
  • 2
    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. – lkartono Aug 02 '17 at 02:51
  • 1
    @2called-chaos 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 useless – sab Dec 10 '18 at 16:03
  • You da man! I don't know I messed up the password. But recreating the keys fixed this. Many thanks! – Khulani M Jun 29 '20 at 22:56
36

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-----"
Dorian
  • 22,759
  • 8
  • 120
  • 116
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.

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • You're correct. The problem was from the way that the pem file was exported from the certificate. The private key was not included. – Matthew Feb 22 '10 at 05:09
  • 1
    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. – tobyc Mar 23 '10 at 21:10
  • I am having the same issue...i pass only my private key ! – Rahul Goyal Nov 22 '16 at 13:36
  • 1
    This solved my problem: https://stackoverflow.com/a/39115092/1180523. 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. – skplunkerin Jul 19 '18 at 17:58
  • 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. – bradw2k May 19 '20 at 22:54
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.

Ninjaxor
  • 876
  • 12
  • 27
4

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-----
  • 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: https://lti-ri.imsglobal.org/ – theotherdy Feb 08 '21 at 19:55
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.

Tyler Collier
  • 11,489
  • 9
  • 73
  • 80
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

Julien
  • 953
  • 9
  • 15
1

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

Waqar UlHaq
  • 6,144
  • 2
  • 34
  • 42
hulksyed07
  • 11
  • 1
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.

Ali Ghanavatian
  • 506
  • 1
  • 6
  • 14
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.

Rafael Bugajewski
  • 1,702
  • 3
  • 22
  • 37