Nodejs TLS с самоподписанным центром сертификации

Фон:


Я пытаюсь установить связь между сервером и одним (должно быть несколько - следовательно, нужен CA) клиент через TLS.

У каждого узла есть сертификат, подписанный общим ЦС. Центр сертификации, в свою очередь, является самоподписанным.

Закрытый ключ каждого узла экспортируется как key.pem. Сертификат каждого узла экспортируется как certificate.crt. Сертификат CA экспортируется как ca.crt. Сертификаты не входят в комплект, а просто экспортируются как есть.

Сервер использует следующую настройку:

var tls = require("tls");
var fs = require("fs");

var options = {
  key: fs.readFileSync("keys/key.pem", "utf8"),
  cert: fs.readFileSync("keys/certificate.crt", "utf8"),

  requestCert: true,
  rejectUnauthorized: true,

  ca: [fs.readFileSync('keys/ca.crt')]
}

var server = tls.createServer(options, function(res) {
  console.log("Client connected");

  console.log('Client connected',
              res.authorized ? 'authorized' : 'unauthorized');

  res.write("Hello World!");
  res.setEncoding("utf8");
  res.pipe(res);
}).listen(3000);

Клиент использует следующую настройку:

var tls = require("tls");
var fs = require("fs");

var options = {
  key: fs.readFileSync("keys/key.pem", "utf8"),
  cert: fs.readFileSync("keys/certificate.crt", "utf8"),

  requestCert: true,
  rejectUnauthorized: true,

  ca: [fs.readFileSync('keys/ca.crt')]
}

var client = tls.connect(3000, options, function(){
  console.log("Connected to server");
  console.log(client.authorized ? "Authorized" : "Not authorized");
});

client.on("data", function(data){
  console.log("Received from server", data);
  client.end();
});

Примечание по ключам / сертификатам:


Ключи и сертификаты генерируются с помощью графического интерфейса / менеджера openssl XCA.

Дерево выглядит следующим образом:  Визуализация цепочки сертификатов

Эта проблема:


Как видите, я использую явную аутентификацию сертификата клиента и хочу запретить любые неразрешенные соединения.

Проблема в том, что клиент не может подключиться, даже если все сертификаты поступают от одного и того же центра сертификации.

Ошибка, которую я получаю как от сервера (когда клиент подключается), так и от клиента (когда он подключается):

Error: socket hang up, code: ECONNRESET

Если я отключу rejectUnauthorized, клиент сможет подключиться, но res.authorized вернет false.

Что заставляет авторизованных клиентов не проходить аутентификацию?


person Alex    schedule 12.12.2015    source источник
comment
Я никогда не видел сертификата без срока годности. Возможно, в этом проблема. Еще нужно проверить, не зашифрованы ли ваши ключи.   -  person rhashimoto    schedule 12.12.2015


Ответы (1)


Ваш код в порядке. Я полагаю, что возникла проблема с вашими сертификатами. Мне запомнился тот факт, что нет срока годности. Я нашел этот Центр сертификации OpenSSL от Джейми Нгуен быть очень полезным. Помните, что Nodejs не поддерживает несколько сертификатов в одном файле сертификата, поэтому, если вы следуете руководству, нет необходимости копировать корневой CA и промежуточный CA в один файл. Вам нужно будет добавить их как отдельные записи файла в аргумент списка CA.

Afaik инструмент xca построен на openssl, поэтому может быть в состоянии сопоставить команды openssl с xca.

person Heino    schedule 18.11.2016