为什么requestjs拒绝与Firefox一起使用的自签名SSL证书?

时间:2015-12-07 16:27:05

标签: node.js ssl self-signed requestjs

这是情况。我创建了一个自签名CA证书,并使用它来签署第二个证书以用于https。 Web服务器是nginx进行SSL终止并反向代理到expressjs应用程序。为了验证信任链是否正确,我在Firefox中安装了CA,并且能够按预期在没有警告的情况下通过https访问网站。此外,我可以使用request.get({url: theUrl, ca: fs.readFileSync("./ca.crt")}, ... 检查服务器的证书,我会看到预期的发行者,特别是主题的预期通用名称。 (注意:此处使用的通用名称是IP地址,以防可能导致问题。)

但是,当我尝试使用requestjs通过nodejs脚本访问服务器时,事情并不顺利。在脚本中,使用以下代码加载CA证书:

Contacting doorman failed: Error: Hostname/IP doesn't match certificate's altnames: 
"IP: <redacted> is not in the cert's list: "

但是我得到了这个错误(为了便于阅读而破了一行,原来是一行):

rejectUnauthorized: false

特别怀疑它似乎是在说“证书清单”是空的。在其他答案中已经在选项中使用了openssl x509 -text,但对于此应用程序来说,这不是一个很好的选择,因为我想要进行身份验证。

如何让requestjs / nodejs信任此证书?

Certificate: Data: Version: 1 (0x0) Serial Number: 3 (0x3) Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=State, L=City, O=Company, CN=www.company.com Validity Not Before: Dec 7 17:19:51 2015 GMT Not After : Oct 14 17:19:51 2025 GMT Subject: C=US, ST=State, L=City, O=Company, CN=1.2.3.4/emailAddress=webmaster@company.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: ... Exponent: 65537 (0x10001) Signature Algorithm: sha256WithRSAEncryption ...

报告的服务器证书的内容
[ req ]
default_bits       = 4096
prompt             = no
encrypt_key        = no

distinguished_name = req_distinguished_name
req_extensions     = v3_req

[ req_distinguished_name ]
countryName            = "US"
stateOrProvinceName    = "State"
localityName           = "City"
organizationName       = "Company"
commonName             = "1.2.3.4"
emailAddress           = "webmaster@company.com"

[ v3_req ]
subjectAltName = IP:1.2.3.4

用于生成该证书的配置文件:

SIGABRT

1 个答案:

答案 0 :(得分:3)

  

主机名/ IP与证书的altnames不匹配:

我的猜测是,您的证书包含URL中仅用作主题(CN)的正确主机名,而不是主题备用名称(SAN),但它包含其他名称作为SAN。标准非常明确,如果给出任何主题备用DNS名称,则不应检查CN,但大多数浏览器仍然检查CN(我认为Safari更严格)。但是node.js实现了严格的行为,因此会失败。

如果我的猜测是正确的(没有证书很难看到),那么必须通过创建正确的证书来解决问题。另一种可能性是你在浏览器和nodejs中使用稍微不同的URL(比如有和没有www前缀)。

编辑:看到你实际使用的证书后....

您在CN中拥有IP地址的证书。虽然大多数浏览器也支持此功能,但这是不对的。 IP地址必须作为ipadress SAN条目而不是CN。 Nodejs只在那里期待它,我认为Safari也是如此严格。请注意,对于IE,您必须将其置于CN或dnsname SAN条目中,因为它们在这种情况下也喜欢与标准相反。因此,为了安全起见,将其作为ipaddress,dnsname,也可能作为CN。