服务器端客户端证书验证

服务器端客户端证书验证

本文介绍了服务器端客户端证书验证,DEPTH_ZERO_SELF_SIGNED_CERT 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用节点 0.10.26 并尝试通过客户端验证建立 https 连接.

I'm using node 0.10.26 and trying to establish https connection with client validation.

服务器代码:

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"的结果作为通用名称":

I've created certificates with following commands, each time providing result of "uname -n" as "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"的情况下进行了测试.

I've run client and server with all compbinations of client's and server's certificates (that is: [(server1, client1), (server1, client2), (server2, client1), (server2, client2)] and for each combination of those server was tested both with default value of "agent" field and with "agent" set to "false".

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

Each time I ran client.js, res.req.connection.authorizationError was set to DEPTH_ZERO_SELF_SIGNED_CERT.

如何通过客户端的证书认证在节点中建立安全连接?

How can I establish secure connection in node with client's certificate authentication?

推荐答案

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

I believe you have two problems, one with your code and one with your certificates.

代码问题出在您的服务器中.您没有像在客户端代码中那样指定 CA 来检查带有 options 属性的客户端证书:

The code issue is in your server. You are not specifying the CA to check client certificates with an options property like you have in your client code:

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

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

The second problem is the one that really causes that DEPTH_ZERO_SELF_SIGNED_CERT error. You are giving all your certificates - CA, server, and client - the same Distinguished Name. When the server extracts the issuer information from the client certificate, it sees that the issuer DN is the same as the client certificate DN and concludes that the client certificate is self-signed.

尝试重新生成您的证书,给每个证书一个唯一的通用名称(使 DN 也是唯一的).例如,将您的 CA 证书命名为Foo CA",将您的服务器证书命名为您的主机名(在本例中为localhost"),将您的客户端命名为其他名称(例如Foo Client 1").

Try regenerating your certificates, giving each one a unique Common Name (to make the DN also unique). For example, name your CA certificate "Foo CA", your server certificate the name of your host ("localhost" in this case), and your client something else (e.g. "Foo Client 1").

这篇关于服务器端客户端证书验证,DEPTH_ZERO_SELF_SIGNED_CERT 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 14:25