最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - My node.js https client always works regardless of certificate validity - Stack Overflow

programmeradmin1浏览0评论

This test program connects to an https server and gets some content. I've checked my server in browsers and with curl and the certificate is working correctly. If I run curl to grab data from the server it correctly complains about the certificate being unknown unless I pass it in with --cacert or turn security off with -k.

So the problem I am having is that although I think my client should be doing certificate authentication and I am telling it where the public certificate is, it just always works. If I remove the ca: option so it has no idea what the certificate is from the server then it silently works. I would like to catch the authentication error but I can't seem to do so.

var https = require('https');
var fs = require('fs');

function main() {

      var data = '';

      var get = https.get({
        path: '/',
        host: 'localhost',
        port: 8000,
        agent: false,
        ca: [ fs.readFileSync('https_simple/cacert.pem') ]

      }, function(x) {

        x.setEncoding('utf8');
        x.on('data', function(c) {data += c});
        x.on('error', function(e) {
          throw e;
        });
        x.on('end', function() {
          console.log('Hai!. Here is the response:');
          console.log(data);
        });

      });

      get.on('error', function(e) {throw e});

      get.end();

    }

main();

This test program connects to an https server and gets some content. I've checked my server in browsers and with curl and the certificate is working correctly. If I run curl to grab data from the server it correctly complains about the certificate being unknown unless I pass it in with --cacert or turn security off with -k.

So the problem I am having is that although I think my client should be doing certificate authentication and I am telling it where the public certificate is, it just always works. If I remove the ca: option so it has no idea what the certificate is from the server then it silently works. I would like to catch the authentication error but I can't seem to do so.

var https = require('https');
var fs = require('fs');

function main() {

      var data = '';

      var get = https.get({
        path: '/',
        host: 'localhost',
        port: 8000,
        agent: false,
        ca: [ fs.readFileSync('https_simple/cacert.pem') ]

      }, function(x) {

        x.setEncoding('utf8');
        x.on('data', function(c) {data += c});
        x.on('error', function(e) {
          throw e;
        });
        x.on('end', function() {
          console.log('Hai!. Here is the response:');
          console.log(data);
        });

      });

      get.on('error', function(e) {throw e});

      get.end();

    }

main();
Share Improve this question asked Apr 13, 2012 at 14:10 justinhjjustinhj 11.3k11 gold badges64 silver badges106 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 10

In order to make this work I needed to upgrade to v0.7.8 (although any v0.7 should be fine) where the rejectUnauthorized functionality has been added to https.get

This combination of options is needed:

agent: false, // or you can supply your own agent, but if you don't you must set to false
rejectUnauthorized: true, 
ca: [ fs.readFileSync('https_simple/cacert.pem') ]

Now if the authentication fails you will get an 'error' event and the request will not go ahead.

See the https.request documentation for details on making your own Agent

The bug fix was committed in this change: https://github.com/joyent/node/commit/f8c335d0

As per the documentation for https.request, the ca option of both https.get and https.request is an option from tls.connect. The documentation for the options to the tls.connect module function states:

ca: An array of strings or Buffers of trusted certificates. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.

Digging into the node.js source, the root certs used can be found here: https://github.com/joyent/node/blob/master/src/node_root_certs.h

So in short, with no authority cert provided as an option to https.get the tls module will attempt to authenticate the connection using the list of root certs anyway.

I do this in npm, using the request module. It goes like this:

var cacert = ... // in npm, this is a config setting
var request = require("request")
request.get({ url: "https://...",
              ca: cacert,
              strictSSL: true })
  .on("response", function (resp) { ... })
  .on("error", function (er) { ... })

The error event will be raised if the ssl isn't valid.

In V 0.6.15 you need to explicitly check whether or not the certificate validation passed or failed.

if (x.connection.authorized === false) {    
   console.log('SSL Authentication failed');
} else if (x.connection.authorized === true) {    
   console.log('SSL Authentication succeeded');
} 
发布评论

评论列表(0)

  1. 暂无评论