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

标签 node.js ssl certificate

我正在使用 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”的结果作为“通用名称”:

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 也唯一)。例如,将您的 CA 证书命名为“Foo CA”,将服务器证书命名为主机名(在本例中为“localhost”),将客户端命名为其他名称(例如“Foo Client 1”)。

关于node.js - 服务器端的客户端证书验证,DEPTH_ZERO_SELF_SIGNED_CERT 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23601989/

相关文章:

使用 OpenSSL 在 Solaris 上编译 C 文件包括

java - 在 Java 中验证证书会引发异常 - 无法找到指向请求目标的有效证书路径

java - 在 Tomcat 中读出传入的证书

security - ' self signed certificate' 是什么意思?

node.js - 循环 Mocha 测试?

node.js - npm ERR cb() 从未调用

Spring Boot 设置 SSL 连接报错

javascript - 循环 javascript promise 追加到数组

javascript - 通过 Nodejs 进行多个 API 连接

java - 如何在已经打开的 SSL session java 中打开 ssl 套接字