Matthew
Matthew

Reputation: 5845

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

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

Upvotes: 50

Views: 64985

Answers (12)

Renny Ren
Renny Ren

Reputation: 107

I encountered the same issue.

When testing the key with:

OpenSSL::PKey::RSA.new(public_key)

it failed with the error: Neither PUB key nor PRIV key: nested asn1 error

However, the same key and code worked perfectly on my local machine. After investigation, I discovered the issue was caused by the OpenSSL version. The Ruby runtime on the problematic server was linked to an outdated OpenSSL version (1.0.1i).

How I Fixed It

1. Check the OpenSSL Version Linked to Ruby
openssl version

the output is 3.0.2, OK.

Next, run the following in Ruby to check the OpenSSL version used by Ruby runtime:

# irb
require 'openssl'
puts OpenSSL::OPENSSL_VERSION

the output is 1.0.1

That means, even though the system OpenSSL version is 3.0.2 on the server, Ruby itself is still using the older version.

2. Upgrade OpenSSL

I reinstalled Ruby to link to the correct OpenSSL version, and the issue was resolved!

rvm reinstall ruby-<your_version> --with-openssl-dir=/usr

Upvotes: 0

valk
valk

Reputation: 9884

Sometimes, you just copy and paste into rails console or to some other editor which thinks its indentation is always great :-) Example:

pubkey = <<~TIL   # Enter, and paster the public key, then TIL

So instead of:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArmbn/dPHJtujSJjR/0Zu
iAJhpt9Z8HsPKf2U9JU1BK3P0Kma/7KVQxM5EvcwqKONeewjL2NCyZclNjPITX5h
TbbUXO5MU/doxbhiU3NgKvCXjlSvj1aoijUkQu4Nd6XKCTFpEtVJ/fdfc/k7eJ95
Hc8aaiP7R+YoDt+GYHxBl1kCDa7aIlGTutfmBR42H0XfEJLDAjkS2SklpSmOlNCi
su9w4w0D/h1c4Pe6ro6Z4YtqW9n3A0GV1OLo4Z5pGG5reQYH2Q1uFo2LiPXTVq8h
AbJ8YsbQ6ZUlMV52NA4NuM8hs2D5H1xrtmUfNP6lLC0zn0J07yYkjSQncU/nSFYH
owIDAQAB
-----END PUBLIC KEY-----

the pubkey becomes:

  -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArmbn/dPHJtujSJjR/0Zu
iAJhpt9Z8HsPKf2U9JU1BK3P0Kma/7KVQxM5EvcwqKONeewjL2NCyZclNjPITX5h
TbbUXO5MU/doxbhiU3NgKvCXjlSvj1aoijUkQu4Nd6XKCTFpEtVJ/fdfc/k7eJ95
Hc8aaiP7R+YoDt+GYHxBl1kCDa7aIlGTutfmBR42H0XfEJLDAjkS2SklpSmOlNCi
su9w4w0D/h1c4Pe6ro6Z4YtqW9n3A0GV1OLo4Z5pGG5reQYH2Q1uFo2LiPXTVq8h
AbJ8YsbQ6ZUlMV52NA4NuM8hs2D5H1xrtmUfNP6lLC0zn0J07yYkjSQncU/nSFYH
owIDAQAB
  -----END PUBLIC KEY-----

Which causes the error above!

Upvotes: 0

Ali Ghanavatian
Ali Ghanavatian

Reputation: 496

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.

Upvotes: 1

hulksyed07
hulksyed07

Reputation: 21

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

Upvotes: 2

Julien
Julien

Reputation: 1037

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

Upvotes: 1

Nikhil Karkera
Nikhil Karkera

Reputation: 51

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-----

Upvotes: 5

Rafael Bugajewski
Rafael Bugajewski

Reputation: 1712

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.

Upvotes: 0

Dorian
Dorian

Reputation: 23989

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-----"

Upvotes: 40

Tyler Collier
Tyler Collier

Reputation: 11988

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.

Upvotes: 3

Ninjaxor
Ninjaxor

Reputation: 1008

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.

Upvotes: 5

2called-chaos
2called-chaos

Reputation: 3078

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.

Upvotes: 39

President James K. Polk
President James K. Polk

Reputation: 42010

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.

Upvotes: 18

Related Questions