Неможливо перевірити підпис аркуша


142

Я використовую node.js request.js для досягнення api. Я отримую цю помилку

[Помилка: UNABLE_TO_VERIFY_LEAF_SIGNATURE]

Всі мої облікові дані точні та дійсні, а сервер - штраф. Я зробив те саме прохання з листоношею.

request({
    "url": domain+"/api/orders/originator/"+id,
    "method": "GET",
    "headers":{
        "X-API-VERSION": 1,
        "X-API-KEY": key
    },
}, function(err, response, body){
    console.log(err);
    console.log(response);
    console.log(body);
});

Цей код просто працює у виконавчому сценарії, наприклад. node ./run_file.js, Це чому? Чи потрібно це запускати на сервері?


Це тривалий знімок, але чи може це бути те, що API не розпізнає агент користувача, переданий вашою програмою вузла?
Гектор Кореа


@HectorCorrea Я вмів чудово читати api у листоноші. Чому вузол не може це зробити? Я спробував змінити агент користувача, не пощастило.
ThomasReggi

Відповіді:


157

Примітка. Наведене нижче небезпечно та дозволить перехоплювати та змінювати вміст API між клієнтом та сервером.

Це теж спрацювало

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';


22
Я доповнив це, і дякую за відповіді, але це активно шкодить вашій безпеці. Ви повинні додати відсутній відповідь на відповідь на @ CoolAJ86 нижче.
mikemaccana

4
Я використовую плагін NodeJS, який називається, nodemailerі nodemailer-smtp-transportпрацювала та сама загальна команда. Вам потрібно додати це до свого createTransportоб’єкта:tls:{rejectUnauthorized: false}
LukeP

3
Я, мабуть, @LukeP однаково незахищений із нодалею. У назві є підказка: якщо щось Un дозволено, ви, як правило, хочете його відхилити за визначенням. Вам потрібно знайти спосіб її авторизації (правильно встановивши сертифікати CA, як уже говорили інші відповіді).
Бруно

@Bruno Я згоден, ви повинні налаштувати його на правильний шлях із сертифікатами. Я просто хотів встановити швидкий тест для демонстрації, щоб код, який я розмістив, - це швидке виправлення. Я мав би передувати цьому у своєму коментарі.
LukeP

1
@mikemaccana Немає проблем із безпекою, якщо запит знаходиться на одному сервері, і ви єдиний власник.
Веб

89

Це не проблема із заявою, а з сертифікатом, який підписує посередник CA. Якщо ви погоджуєтесь з цим фактом і все ще хочете продовжити, додайте наступні, щоб запитувати варіанти:

rejectUnauthorized: false

Повний запит:

request({
    "rejectUnauthorized": false,
    "url": domain+"/api/orders/originator/"+id,
    "method": "GET",
    "headers":{
        "X-API-VERSION": 1,
        "X-API-KEY": key
    },
}, function(err, response, body){
    console.log(err);
    console.log(response);
    console.log(body);
});

У мене ця проблема зараз на роботі. Я подав квиток на ІТ, в якому говорив, що SSL може бути неправильно налаштований - вони сказали мені, що я божевільний. Чи є якась інформація, яку я можу надати їм для вирішення цього питання?
blakev

Це насправді не правильно: як згадуються CoolAJ86 та hectorcorrea, сертифікат дійсний, але його підписує посередник CA.
mikemaccana

80

Безпечне рішення

Замість того, щоб вимкнути безпеку, ви можете додати необхідні сертифікати до ланцюга. Спочатку встановіть пакет ssl-root-cas з npm:

npm install ssl-root-cas

Цей пакет містить безліч посередницьких сертифікатів, яким браузери довіряють, але вузол не робить.

var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()

Додасть відсутні сертифікати. Дивіться тут для отримання додаткової інформації:

https://git.coolaj86.com/coolaj86/ssl-root-cas.js

Також див. Наступну відповідь нижче


2
Чи Http-клієнт не використовує сертифікат Windows Trusted Root Certification Autorities?
Річард Коллетт

1
вузол використовує сервіси мозілла, вбудовані у двійковий файл, і переосмислює їх щоразу, коли ви постачаєте власний caмасив. Я не знаю, чи буде його модуль http також звертатись до ланцюга ОС. Однак, згортання на OS X, здається, використовує лише ланцюг ОС та не дозволяє вказувати certs вручну.
coolaj86

Чи потрібно це запускати для кожного процесу чи я можу його запустити один раз і оновити свої сертифікати в усьому світі?
Джошуа Снайдер

Сертифікати зберігаються в потенційно двох місцях: (1) вбудований у node.js бінарний (2) сховище ключів операційної системи. Якщо ваш сертифікат застарів, вам потрібно буде включити це у свій запущений код. Він не змінює бінарний вузол, ані вашу операційну систему - лише папку проекту.
coolaj86

1
@Sunkas Саме так повідомляються повідомлення про помилки. Я не знаю, як це простіше пояснити. Це файл лише для читання, і його неможливо редагувати.
coolaj86

45

Рішення CoolAJ86 правильне, і воно не загрожує вашій безпеці, як відключення всіх перевірок за допомогою rejectUnauthorizedабо NODE_TLS_REJECT_UNAUTHORIZED. Тим не менш, вам може знадобитися ввести додатковий сертифікат CA чітко.

Спочатку я спробував кореневі CA, включені модулем ssl-root-cas :

require('ssl-root-cas/latest')
  .inject();

Я все-таки закінчився UNABLE_TO_VERIFY_LEAF_SIGNATUREпомилкою. Потім я дізнався, хто видав сертифікат на веб-сайт, до якого я підключався за допомогою аналізатора COMODO SSL , завантажив сертифікат цього органу і спробував додати лише цей:

require('ssl-root-cas/latest')
  .addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

Я закінчив з іншого помилкою: CERT_UNTRUSTED. Нарешті, я ввів додаткові кореневі ЦА і включив "мій" (мабуть, посередник) СА, який працював:

require('ssl-root-cas/latest')
  .inject()
  .addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

1
Я підключався до веб-сайту із сертифікованим сертифікатом, виданим COMODO High-Assurance Secure Server CA. Я завантажив сертифікат зі сторінки їх завантажень .
Фердинанд Прантл

2
Дякую! Для моєї проблеми мені потрібно було додати всю ланцюжок certs, щоб подолати цю помилку. Для інших посилань цей пост показав мені, як легко експортувати потрібні файли pem через Firefox: superuser.com/a/97203
mfink

Ну дякую за допомогу. У моєму випадку, врешті-решт це була погана конфігурація SSL-сервера, а не вузла. Не всі проміжні серти були встановлені на сервері.
Скотт Юнгвірт

якщо ви отримаєте cert як .cerзапуск, openssl x509 -inform DER -in YOUR_CERTIFICATE.cer -out YOUR_CERTIFICATE.crtконвертуйте його .crtзаздалегідь
0x1gene

8

У програмі Create React (де ця помилка також виникає, і це питання є результатом №1 Google), ви, ймовірно, використовуєте HTTPS=true npm startта proxy(in package.json), який переходить до деякого HTTPS API, який сам підписується під час розробки.

Якщо це так, розгляньте наступні зміни proxy:

"proxy": {
  "/api": {
    "target": "https://localhost:5001",
    "secure": false
  }
}

secure вирішує, перевіряє проксі-сервер WebPack ланцюг сертифікатів чи ні, і відключає, що забезпечує сертифікат самопідписання API не перевірений, щоб отримати ваші дані.


4

Це може бути дуже заманливо зробити rejectUnauthorized: falseабо , process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';але не робіть цього! Це піддає вас людині середніх атак.

Інші відповіді вірні в тому, що питання полягає в тому, що ваш сертифікат "підписаний посередником". Для цього є просте рішення, яке не вимагає сторонніх бібліотек на кшталт ssl-root-casабо введення будь-яких додаткових ЦС у вузол.

Більшість клієнтів https у параметрах підтримки вузлів, які дозволяють вказати CA на запит, що вирішить UNABLE_TO_VERIFY_LEAF_SIGNATURE. Ось простий приклад використання вбудованого httpsмодуля вузла .

import https from 'https';

const options = {
  host: '<your host>',
  defaultPort: 443,
  path: '<your path>',
  // assuming the bundle file is co-located with this file
  ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
  headers: {
    'content-type': 'application/json',
  }
};
https.get(options, res => {
  // do whatever you need to do
})

Якщо ви можете налаштувати налаштування ssl на своєму хостинг-сервері, найкращим рішенням буде додати проміжні сертифікати до вашого хостинг-провайдера. Таким чином, клієнту-запитувачу не потрібно вказувати ЦС, оскільки він включений у сам сервер. Я особисто використовую namecheap + heroku. Хитрість для мене полягала в тому, щоб створити один .crt файл із cat yourcertificate.crt bundle.ca-bundle > server.crt. Потім я відкрив цей файл і додав новий рядок після першого сертифіката. Ви можете прочитати більше на

https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/installing-an-ssl-certificate-on-heroku-ssl


Ця помилка здебільшого в локальному середовищі, а не у виробництві, тож якщо вам належить зробити це добре: process.env ['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
Vivex

@Vivex - це не нормально робити це в локальному середовищі, якщо вся справа в тому, щоб перевірити, як працюють ваші SSL-серти і як вони проходять ...
dwanderson

2

Просто поклавши це на випадок, якщо це комусь допоможе, мій випадок був іншим і трохи дивним. Я отримував це за запитом, до якого звертався через суперагент - проблема не мала нічого спільного з сертифікатами (які були налаштовані належним чином), і все з тим, що я передав результат суперагенту через зворотний зворотний виклик модуля асинхронізації . Для виправлення: Замість того, щоб передавати весь результат, просто пройдіть result.bodyзворотний виклик водоспаду.


2

У мене були ті самі проблеми. Я дотримувався рішення @ThomasReggi та @ CoolAJ86 і працював добре, але рішенням я не задоволений.

Оскільки проблема "UNABLE_TO_VERIFY_LEAF_SIGNATURE" трапляється через рівень конфігурації сертифікації.

Я приймаю рішення @thirdender, але його часткове рішення. Що стосується офіційного веб-сайту nginx , вони чітко згадували сертифікат, який повинен поєднувати сертифікат сервера та сертифіковані сертифікати.

введіть тут опис зображення


2

Ви також можете спробувати, встановивши strictSSL до false, як це:

{  
   url: "https://...",
   method: "POST",
   headers: {
        "Content-Type": "application/json"},
   strictSSL: false
}

Це працює, якщо ваше надсилання з програми Node JS, приголомшливо !!
Ally Makongo

0

У мене виникла проблема з конфігурацією Apache після встановлення сертифіката GoDaddy на субдомен. Спочатку я вважав, що це може бути проблема з тим, що Node не надсилає індикатор імені сервера (SNI), але це було не так. Аналізуючи SSL-сертифікат субдомена за допомогою https://www.ssllabs.com/ssltest/ повернув помилку Ланцюгові проблеми: Неповні .

Після додавання наданого GoDaddy gd_bundle-g2-g1.crtфайла через SSLCertificateChainFileдирективу Apache, Node вдалося підключитися через HTTPS і помилка усунулася.


0

Ви повинні включити Проміжний сертифікат на свій сервер. Це вирішує [Помилка: UNABLE_TO_VERIFY_LEAF_SIGNATURE]


0

Іншим підходом до безпечного вирішення цього питання є використання наступного модуля.

node_extra_ca_certs_mozilla_bundle

Цей модуль може працювати без будь-якої модифікації коду, генеруючи файл PEM, який включає всі кореневі та проміжні сертифікати, яким довіряє Mozilla. Ви можете використовувати таку змінну середовища (працює з Nodejs v7.3 +),

NODE_EXTRA_CA_CERTS

Для створення файлу PEM для використання з вищевказаною змінною середовища. Ви можете встановити модуль за допомогою:

npm install --save node_extra_ca_certs_mozilla_bundle

а потім запустіть сценарій вузла зі змінною середовища.

NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node your_script.js

Інші способи використання створеного файлу PEM доступні за посиланням:

https://github.com/arvind-agarwal/node_extra_ca_certs_mozilla_bundle

ПРИМІТКА: Я автор вищевказаного модуля.


0

Якщо ви перейдете до цього потоку, оскільки використовуєте модуль postgres / pg вузла, є краще рішення, ніж налаштування NODE_TLS_REJECT_UNAUTHORIZEDабо rejectUnauthorized, що призведе до небезпечних з'єднань.

Натомість налаштуйте параметр "ssl" для відповідності параметрам для tls.connect :

{
  ca: fs.readFileSync('/path/to/server-ca.pem').toString(),
  cert: fs.readFileSync('/path/to/client-cert.pem').toString(),
  key: fs.readFileSync('/path/to/client-key.pem').toString(),
  servername: 'my-server-name' // e.g. my-project-id/my-sql-instance-id for Google SQL
}

Я написав модуль для допомоги при розборі цих параметрів від змінних оточення , як PGSSLROOTCERT, PGSSLCERTі PGSSLKEY:

https://github.com/programmarchy/pg-ssl


-1

Наступні команди працювали на мене:

> npm config set strict-ssl false
> npm cache clean --force

Проблема полягає в тому, що ви намагаєтесь встановити модуль із сховища з поганим або ненадійним сертифікатом SSL [Secure Sockets Layer]. Після того, як ви очистите кеш, ця проблема буде вирішена. Можливо, вам доведеться згодом повернути її до справжнього.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.