Reputation: 5845
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
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).
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.
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
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
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
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
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
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
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
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
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
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
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
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