Node.JS + HTTPS + 客户端证书 = 问题

4
我一直在尝试让Node.JS与SSL和客户端证书一起工作。最初,我尝试使用restify(请参见我的问题here)。当我无法让它工作时,我退回并尝试找到一个例子来说明我想要实现的目标。我尝试了这个例子,但我收到了一个奇怪的错误。

代码如下:

服务器:

var sys = require("sys");
var fs = require("fs");
var https = require("https");

var options = {
  key: fs.readFileSync("../certs/server.key"),
  cert: fs.readFileSync("../certs/server.crt"),
  ca: fs.readFileSync("../certs/ca.crt"),
  requestCert: true,
  rejectUnauthorized: true
};

https.createServer(options, function (req, res) {
  console.log(req);
  res.writeHead(200);
  sys.puts("request from: " + req.connection.getPeerCertificate().subject.CN);
  res.end("Hello World, " + req.connection.getPeerCertificate().subject.CN + "\n");
}).listen(8080);

sys.puts("server started");

客户:

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

var options = {
    host: 'localhost',
    port: 8080,
    path: '/hello',
    method: 'GET',
    key: fs.readFileSync("../certs/user.key"),
    cert: fs.readFileSync("../certs/user.crt"),
    ca: fs.readFileSync("../certs/ca.crt"),
    passphrase: 'thepassphrase'
};

var req = https.request(options, function(res) {
    console.log("statusCode: ", res.statusCode);
    console.log("headers: ", res.headers);

    res.on('data', function(d) {
        process.stdout.write(d);
    });
});

req.end();

req.on('error', function(e) {
    console.error(e);
});

运行 test-client.js 会产生以下结果:
{ [Error: socket hang up] code: 'ECONNRESET' }

尝试使用curl完成相同的事情:

curl -k -v --key user.key --cert user.crt:thepassphrase --cacert ca.crt https://localhost:8080/hello

产出:

* About to connect() to localhost port 8080 (#0)
*   Trying 127.0.0.1... connected
* successfully set certificate verify locations:
*   CAfile: ca.crt
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS handshake, CERT verify (15):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* Unknown SSL protocol error in connection to localhost:8080 
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to localhost:8080

如果我想要更进一步,需要客户端证书验证,我该如何处理?
2个回答

3

把这个服务器放在nginx后面怎么样?

这听起来可能很复杂,或者会增加很多开销,但我向你保证它非常简单,而且nginx的SSL处理也很容易。

查找使用nginx进行代理示例)。

P.S
两个应用程序可以并且可能驻留在同一台服务器上。


这是一个有趣的答案。Nginx能否将关于用户证书的信息传递到最终目标URL?可能通过向URL添加一些参数来实现? - Chris
很高兴听到这个消息!最终你是如何处理证书转发通过 Nginx 的问题的呢?我只是好奇。 - Poni
1
我没有通过nginx转发证书,@Poni,我使用证书对nginx进行了身份验证,并继续使用常规的无客户端证书https。理论是除非一切匹配,否则nginx不会传递对话。 - Chris
不知道...不是我。我猜想这个踩的原因是虽然这个回答对我有用,但它并没有真正回答问题。 - Chris
2
@Poni,我也遇到了同样的问题。不过,有没有什么解决方案的想法,不涉及nginx并直接与node一起工作? - psiphi75
@psiphi75,请看下面我提供的另一种解决方案。 - michielbdejong

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接