Я пытаюсь настроить сервер и некоторые клиенты, использующие TLS в узле. Я использую самозаверяющие сертификаты на клиентах и на сервере. Сервер работает нормально, но когда я пытаюсь подключиться к клиенту, я получаю следующую ошибку на стороне клиента:
Error: DEPTH_ZERO_SELF_SIGNED_CERT
Создание сертификата
Сертификат CA:
# Create key to sign our own certs. Act like as our own a CA.
echo "SecuresPassphrase" > ./tls/passphrase.txt
openssl ecparam -name secp521r1 -genkey -noout -out ./tls/certs/ca/ca.plain.key # Generate private key
openssl pkcs8 -topk8 -passout file:./tls/passphrase.txt -in ./tls/certs/ca/ca.plain.key -out ./tls/certs/ca/ca.key # Generate encrypted private key
rm ./tls/certs/ca/ca.plain.key; # Remove unencrypted private key
# Generate CA cert
openssl req -config ./openssl/oid_file -passin file:./tls/passphrase.txt -new -x509 -days 365 -key ./tls/certs/ca/ca.key -out ./tls/certs/ca/ca.crt
Сертификат сервера:
openssl ecparam -name secp521r1 -genkey -noout -out ./tls/certs/servers/server.key # Generate server private key
openssl req -config ./openssl/oid_file -new -key ./tls/certs/servers/server.key -out ./tls/certs/servers/server.csr # Generate signing request
openssl x509 -passin file:./tls/passphrase.txt -req -days 365 -in ./tls/certs/servers/server.csr -CA ./tls/certs/ca/ca.crt -CAkey ./tls/certs/ca/ca.key -CAcreateserial -out ./tls/server.crt
mv ./tls/server.crt ./tls/certs/servers/
Сертификат клиента:
Клиентский сертификатсертификаты создаются внутри цикла bash, переменная ${name}
содержит имя клиента и меняет каждую итерацию.
openssl ecparam -name secp521r1 -genkey -noout -out ./tls/certs/clients/${name}/client.key
openssl req -config ./openssl/oid_file -new -key ./tls/certs/clients/${name}/client.key -out ./tls/certs/clients/${name}/client.csr
openssl x509 -passin file:./tls/passphrase.txt -req -days 365 -in ./tls/certs/clients/${name}/client.csr -CA ./tls/certs/ca/ca.crt -CAkey ./tls/certs/ca/ca.key -CAcreateserial -out ./tls/client.crt
mv ./tls/client.crt ./tls/certs/clients/${name}/
Я также пытаюсь использовать Perfect Forward Secrecy, используя эфемерный обмен Диффи-Хеллмана. Параметры для клиентов и сервера создаются как openssl dhparam -outform PEM -out ./tls/params/servers/server/dhparams.pem 2048
Код сервера:
return new Promise(resolve => {
// Define parameters of TLS socket
const options = {
rejectUnauthorized: false,
requestCert: true,
// Secure Context Parameters
ca: [fs.readFileSync("tls/certs/ca/ca.crt")],
cert: fs.readFileSync("tls/certs/servers/server.crt"),
key: fs.readFileSync("tls/certs/servers/server.key"),
ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:!RC4:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!SRP:!CAMELLIA",
dhparam: fs.readFileSync("tls/params/servers/server/dhparams.pem"),
ecdhCurve: tls.DEFAULT_ECDH_CURVE,
minVersion: "TLSv1.2"
};
// Iniciar servidor TLS
this.SERVIDOR = tls.createServer(options, function (socket) {
console.log("Server created.");
});
this.SERVIDOR.listen(this.puerto, this.direccion, function () {
console.log("Listening");
});
this.SERVIDOR.on("secureConnection", (socket) => this.handleRequest(socket));
this.SERVIDOR.on("tlsClientError", (error) => console.log("Error client TLs. %s", error));
});
Код клиента:
return new Promise(resolve => {
// Define parameters of TLS socket
const options = {
host: this.NODE,
port: this.NODE_PORT,
rejectUnauthorized: false,
secureContext: tls.createSecureContext({
ca: [fs.readFileSync("tls/certs/ca/ca.crt")],
cert: fs.readFileSync("tls/certs/clients/" + this.NAME + "/client.crt"),
key: fs.readFileSync("tls/certs/clients/" + this.NAME + "/client.key"),
ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:!RC4:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!SRP:!CAMELLIA",
dhparam: fs.readFileSync("tls/params/clients/" + this.NAME + "/dhparams.pem"),
ecdhCurve: tls.DEFAULT_ECDH_CURVE,
minVersion: "TLSv1.2"
})
};
// Initialize TLS socket
this.WEB_SOCKET = tls.connect(options, function () {
// Check if TLS auth worked
if (this.authorized) {
console.log("Connection authorized by a Cert. Authority ");
} else {
console.log("Authorization not granted. Error: " + this.authorizationError);
}
});
Что я пробовал:
- Установите для rejectUnauthorized значение
false
. - Попытался запустить код с помощью
NODE_TLS_REJECT_UNAUTHORIZED = "0";
. Это не сработало, и я думаю, что это не очень хороший вариант для производства. - Проверял похожие вопросы на SO, этот выглядит очень похоже на мою проблему. Но самый голосующий ответ от 2014 года, и я не смог найти слишком много информации о выдающемся имени в документах .
- Я проверил сертификаты, используя
openssl x509 -in *.cert -text
, и они выглядели хорошо.
¿Я неправильно генерирую сертификаты? Любая помощь приветствуется. Спасибо!
РЕДАКТИРОВАТЬ. 16/10/2019 В коде была проблема, я не использовал resolve();
, когда розетки работали. Та же проблема остается ... НО , несмотря на получение ошибки авторизации на клиенте, сервер запускает событие «secureConnection», и сообщения обмениваются. ¿Имеет ли это смысл? * Да, это имеет смысл, поскольку сервер принимает несанкционированные соединения. Если я настрою сервер на отклонение несертифицированных соединений, клиенты зависнут *