Why does requestjs reject a self-signed SSL certificate that works with Firefox?

断了今生、忘了曾经 提交于 2019-12-11 10:34:26

问题


Here's the situation. I created a self-signed CA certificate, and used it to sign a second certificate for use with https. The web server is nginx doing SSL termination and reverse proxying to an expressjs application. To verify that the chain of trust is correct, I installed the CA in Firefox and was able to access the website over https without warnings, as expected. Further, I can inspect the server's certificate with openssl x509 -in server.crt -text -noout, and I see both the expected issuer and in particular the expected common name for the subject. (Note: the common name being used here is an IP address, in case that might cause trouble.)

However, when I try to access the server via a nodejs script using requestjs, things don't go so smoothly. In the script, the CA certificate is loaded using code like this:

request.get({url: theUrl, ca: fs.readFileSync("./ca.crt")}, ...

But I get this error (line broken for readability, original is one line):

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

It's particularly suspicious that it seems to be saying that the "cert's list" is empty. Using rejectUnauthorized: false in the options has been suggested in other answers, but it isn't a great option for this application because I want to have the identity validation.

How can I make requestjs/nodejs trust this certificate?


Contents of the server certificate, as reported by openssl x509 -text

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

And the config file used to generate that certificate:

[ 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

回答1:


Hostname/IP doesn't match certificate's altnames:

My guess is that your certificate contains the correct hostname used in the URL only as subject (CN) and not as subject alternative name (SAN), but that it contains other names as SAN. The standard is quite clear that if any subject alternative DNS names are given the CN should not be checked, but most browsers check CN anyway (I think Safari is more strict). But node.js implements the strict behavior and will thus fail.

If my guess is right (hard to see without certificate) then the issue has to be fixed by creating a correct certificate. Another possibility is that you use a slightly different URL in browser and nodejs (like with and without www prefix).

EDIT: after seeing what certificate you actually use....

You have a certificate with an IP address in the CN. While this is also supported by most browsers it is not right. An IP address must be given as ipadress SAN entry and not as CN. Nodejs expects it only there and I think that Safari is also that strict. Note that for IE you have to put it either into CN or as dnsname SAN entry just because they like to behave contrary to the standard in this case too. Thus to be on the safe side put it as ipaddress, dnsname and maybe as CN too.



来源:https://stackoverflow.com/questions/34138384/why-does-requestjs-reject-a-self-signed-ssl-certificate-that-works-with-firefox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!