42

当使用 OpenSSL::PKey::RSA 模块通过传递一个 .pem 文件来构建公钥时,响应的原因是什么:

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

这是来源:

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
4

10 回答 10

36

我有同样的问题,它有不同的原因。现在猜猜看:)

...

该死的密码是错误的 :( 为那个“解决方案”搜索了 3 天。可能是“对不起,伙计,那是错误的密码!”而不是“嵌套 asn1 错误”恕我直言,但无论如何,也许这会对某人有所帮助。

于 2012-10-22T12:31:04.563 回答
24

dotenv例如,如果您使用的是换行符",则必须将值括起来并带有\n换行符。

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIICW  ... UcuUtU0eIl\n-----END RSA PRIVATE KEY-----"
于 2017-04-12T22:47:54.630 回答
15

pem 文件不是公钥,它是 base64 编码的 X509 证书,在其众多字段中包含一个公钥。我不知道 Ruby 或 OpenSSL ruby​​ 模块,但我会寻找一些读取 PEM 文件并输出 X509 证书的函数,然后是另一个从证书中提取公钥的函数。

于 2010-02-20T00:50:50.377 回答
4

我也有类似的问题,但对我来说,我一开始并没有为我的 id_rsa.pub 文件创建 pem 文件。对我来说,我需要用我现有的公钥创建一个 pem 文件:

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

然后我将该 OpenSSL 字符串复制到正在使用它的测试文件中。最终对我来说是这样的。

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

之后,该方法停止抛出该错误。

于 2013-03-19T22:11:49.427 回答
4

确保您的.pem文件采用这种格式。

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-----
于 2019-03-28T05:20:52.590 回答
3

我的问题是OpenSSL::PKey::RSA.new()想要文件内容而不是文件路径。因此,使用这样的东西是有效的:

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

OP 已经在这样做了,但希望这会对某人有所帮助。因为它假定它是文件内容而不是文件路径,所以即使您提供无效路径,您也不会收到警告。

于 2014-07-10T05:25:07.370 回答
1

我在测试中使用 Webrick 并尝试使用错误的类实例化我的私钥导致我收到该错误消息:

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

但这有效

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

掌心

于 2019-10-29T13:39:33.067 回答
1

将dotenv与 rails一起使用时出现此错误。问题不在于dotenv gem。通过打印ENV['PRIVATE_KEY']确认它正在分配正确的值

出现问题是因为我正在使用ERB处理在YAML文件中加载此值,并导致删除\n字符,从而使该值无效

我发现的解决方法是直接使用ENV['PRIVATE_KEY']而不是通过YAML

于 2020-02-21T10:44:13.827 回答
1

如果上述答案均无效,则可能是由于算法不正确。较新的公钥是使用ECDSAalgorithm 而不是RSA,所以OpenSSL::PKey::EC应该使用 class 来代替。

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

于 2020-09-07T07:48:53.190 回答
0

在我的情况下,该函数需要一个私钥,而证书存储在某个变量中。用私钥交换输入修复了错误。

于 2017-10-18T19:43:20.300 回答