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

Viewed 52351

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

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.

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

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

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

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.

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.

Related