node.js - 在服务器端,DEPTH_ZERO_SELF_SIGNED_CERT错误,客户端证书验证

我使用node 0.10.26,并尝试与客户端验证建立https连接。

服务器代码:


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

process.env.NODE_TLS_REJECT_UNAUTHORIZED ="0";

var options = {
 key: fs.readFileSync('ssl/server1.key'),
 cert: fs.readFileSync('ssl/server1.pem'),
 requestCert: true,
 rejectUnauthorized: false,
};

var server = https.createServer(options, function (req, res) {
 if (req.client.authorized) {
 res.writeHead(200, {"Content-Type":"application/json"});
 res.end('{"status":"approved"}');
 console.log("Approved Client", req.client.socket.remoteAddress);
 } else {
 console.log("res.connection.authroizationError:" + res.connection.authorizationError);
 res.writeHead(403, {"Content-Type":"application/json"});
 res.end('{"status":"denied"}');
 console.log("Denied Client" , req.client.socket.remoteAddress);
 }
});

server.on('error', function(err) {
 console.log("server.error:" + err);
});

server.on("listening", function () {
 console.log("Server listeining");
});

server.listen(5678);

客户端代码:


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

var options = {
 host: 'localhost',
 port: 5678,
 method: 'GET',
 path: '/',
 headers: {},
 agent: false,
 key: fs.readFileSync('ssl/client2.key'),
 cert: fs.readFileSync('ssl/client2.pem'),
 ca: fs.readFileSync('ssl/ca.pem')
};

process.env.NODE_TLS_REJECT_UNAUTHORIZED ="0";

var req = https.request(options, function(res) {
 console.log(res.req.connection.authorizationError);
});

req.on("error", function (err) {
 console.log('error: ' + err);
});

req.end();

我已经使用以下命令创建了证书,每次将"uname -n"的结果作为"Common Name"提供:


openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -days 999 -out ca.pem

openssl genrsa -out server1.key 1024
openssl req -new -key server1.key -out server1.csr
openssl x509 -req -days 999 -in server1.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out server1.pem

openssl genrsa -out client1.key 1024
openssl req -new -key client1.key -out client1.csr
openssl x509 -req -days 999 -in client1.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out client1.pem

openssl genrsa -out server2.key 1024
openssl req -new -key server2.key -out server2.csr
openssl x509 -req -days 999 -in server2.csr -CA server1.pem -CAkey server1.key - set_serial 02 -out server2.pem

openssl genrsa -out client2.key 1024
openssl req -new -key client2.key -out client2.csr
openssl x509 -req -days 999 -in client2.csr -CA client1.pem -CAkey client1.key -set_serial 02 -out client2.pem

我已经使用客户端证书和服务器证书的所有组合来运行客户端和服务器(即:[(server1,client1),(server1,client2),(server2,client1),(server2,client2)]并针对这些服务器的每种组合都使用默认值“ agent ”字段和“ agent “设置为” false “。

每次运行client.js时,res.req.connection.authorizationError被设置为DEPTH_ZERO_SELF_SIGNED_CERT。

在node中,如何使用客户端的证书身份验证建立安全连接?

时间:

我相信你有两个问题,一个是代码,另一个是证书。

代码问题在你的服务器上,你没有指定CA来使用options属性检查客户端证书,就像在客户端代码中一样:


ca: fs.readFileSync('ssl/ca.pem'),

第二个问题是真正导致DEPTH_ZERO_SELF_SIGNED_CERT错误的那个,您将为所有证书(CA,服务器和客户端)赋予相同的专有名称。当服务器从客户端证书中提取颁发者信息时,它看到颁发者DN与客户端证书DN相同,并得出客户端证书是自签名的。

尝试重新生成证书,为每个证书提供一个唯一的公共名称(使DN也是唯一)。

对于想要使用自签名证书的人,答案是将rejectUnauthorized: false添加到https.request选项。

只需将strictSSL: false添加到options

...