Fout: kan het eerste certificaat in nodejs niet verifiëren

Ik probeer een bestand van de jira-server te downloaden met een URL, maar ik krijg een foutmelding.
hoe een certificaat in de code op te nemen om te verifiëren?

Fout:

Error: unable to verify the first certificate in nodejs
at Error (native)
    at TLSSocket.<anonymous> (_tls_wrap.js:929:36)
  at TLSSocket.emit (events.js:104:17)
at TLSSocket._finishInit (_tls_wrap.js:460:8)

Mijn Nodejs-code:

var https = require("https");
var fs = require('fs');
var options = {
    host: 'jira.example.com',
    path: '/secure/attachment/206906/update.xlsx'
};
https.get(options, function (http_res) {
    var data = "";
    http_res.on("data", function (chunk) {
        data += chunk;
    });
    http_res.on("end", function () {
        var file = fs.createWriteStream("file.xlsx");
        data.pipe(file);
    });
});

Antwoord 1, autoriteit 100%

Probeer het juiste rootcertificaat toe te voegen

Dit is altijd een veel veiligere optie dan het blindelings accepteren van niet-geautoriseerde eindpunten, die op hun beurt alleen als laatste redmiddel moeten worden gebruikt.

Dit kan zo simpel zijn als toevoegen

require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create();

naar je sollicitatie.

Het SSL Root CAs npm-pakket(zoals hier gebruikt) is een zeer handig pakket met betrekking tot dit probleem.


Antwoord 2, autoriteit 72%

Nog een vuile hack, die al je verzoeken onveilig maakt:

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0

Antwoord 3, Autoriteit 65%

unable to verify the first certificate

niet verifiëren

De certificaatketen is onvolledig.

Het betekent dat de webserver waarmee u verbinding maakt, verkeerd is geconfigureerd en niet het tussencertificaat in de certificaatketen heeft opgenomen.

Certificaatketen

Het lijkt hoogstwaarschijnlijk als volgt:

  1. Servercertificaat – slaat een certificaat op dat wordt ondertekend door tussenprediate.
  2. Intermediate certificaat – slaat een certificaat op dat is ondertekend door root.
  3. rootcertificaat – slaat een zelfondertekend certificaat op.

Intermediate certificaat moet op de server worden geïnstalleerd, samen met het servercertificaat.
Rootcertificaten zijn ingebed in de softwaretoepassingen, browsers en besturingssystemen.

De applicatie die het certificaat dient, moet de volledige keten verzenden, dit betekent het servercertificaat zelf en alle tussenproducten. Het root-certificaat moet door de klant bekend zijn.

Maak het probleem opnieuw

Ga naar https://incomplete-chain.badssl.com met behulp van uw browser.

Het toont geen fout (hangslot in de adresbalk is groen).
Het is omdat browsers de neiging hebben om de keten te voltooien als deze niet van de server wordt verzonden.

Nu, verbinding maken met https://incomplete-chain.badssl.com met behulp van knooppunt:

// index.js
const axios = require('axios');
axios.get('https://incomplete-chain.badssl.com')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Logs: “FOUT: Kan het eerste certificaat niet verifiëren.

Oplossing

U moet zelf de certificaatketen voltooien.

om dat te doen:

1: U moet het ontbrekende tussentijdse certificaat in .pemformaat, vervolgens

2A: Extend Node’s ingebouwde certificaatwinkel met behulp van NODE_EXTRA_CA_CERTS,

2b: of geef uw eigen certificaatbundel (tussenproducten en root) met caOPTIE.

1. Hoe krijg ik een intermediair certificaat?

Gebruik openssl(Wordt geleverd git voor Windows ).

Sla het certificaatgegevens van de externe server op:

openssl s_client -connect incomplete-chain.badssl.com:443 -servername incomplete-chain.badssl.com | tee logcertfile

We zijn op zoek naar de Emittent (het tussentijdse certificaat is de Emittent / Ondertekenaar van het servercertificaat):

openssl x509 -in logcertfile -noout -text | grep -i "issuer"

Het zou u URI van het ondertekeningscertificaat moeten geven. Download het:

curl --output intermediate.crt http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt

Converteer het tot nu toe naar .pem:

openssl x509 -inform DER -in intermediate.crt -out intermediate.pem -text

2A. NODE_EXTRA_CERTS

Ik gebruik cross-env om omgevingsvariabelen in te stellen in package.jsonbestand:

"start": "cross-env NODE_EXTRA_CA_CERTS=\"C:\\Users\\USERNAME\\Desktop\\ssl-connect\\intermediate.pem\" node index.js"

2B. caOPTIE

Deze optie gaat het ingebouwde root-cas van het knooppunt overschrijven.

Daarom moeten we onze eigen root ca maken. Gebruik SSL-root-cas .

Maak vervolgens een aangepaste httpsAgent geconfigureerd met onze certificaatbundel (root en tussenproduct). Geef deze agent door op axiosbij het maken van aanvraag.

// index.js
const axios = require('axios');
const path = require('path');
const https = require('https');
const rootCas = require('ssl-root-cas').create();
rootCas.addFile(path.resolve(__dirname, 'intermediate.pem'));
const httpsAgent = new https.Agent({ca: rootCas});
axios.get('https://incomplete-chain.badssl.com', { httpsAgent })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

In plaats van een aangepaste httpsAgent te maken en het doorgeven aan axios, kunt u de certificaten plaatsen op de httpsGlobal Agent:

// Applies to ALL requests (whether using https directly or the request module)
https.globalAgent.options.ca = rootCas;

BRILDEN:

  1. https: //levelup.gitconnected.com/How-to-resolk-certificate-rors-in-nodejs-App-involment-Ssl-calls-781Ce48Daded
  2. https://www.npmjs.com/package/ssl-root-cas
  3. https://github.com/nodjs/node/issues/16336
  4. HTTPS: //www.namecheap.com/support/knowledbase/article.aspx/9605/69/how-to-check-ca-chain-installation
  5. HTTPS: // superuser.com/questions/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file/
  6. Hoe te converteren .crt naar .pem

Antwoord 4, Autoriteit 33%

Voor niet in staat om het eerste certificaat in Nodejs te verifiëren, is niet geautoriseerd verwerpen nodig

request({method: "GET", 
        "rejectUnauthorized": false, 
        "url": url,
        "headers" : {"Content-Type": "application/json",
        function(err,data,body) {
    }).pipe(
       fs.createWriteStream('file.html'));

Antwoord 5, Autoriteit 22%

De server die u probeert te downloaden, kan slecht worden geconfigureerd. Zelfs als het in uw browser werkt, is het mogelijk niet inclusief alle openbare certificaten in de keten die nodig is voor een cache-lege klant om te verifiëren.

Ik raad aan om de site te controleren in de SSLlabs-tool: https://www.ssllabs.com/ssltest/

Zoek naar deze fout:

De certificaatketen van deze server is onvolledig.

En dit:

Kettingproblemen………Onvolledig


Antwoord 6, autoriteit 5%

Dit heeft het voor mij opgelost, van https://www.npmjs.com /package/ssl-root-cas

// INCORRECT (but might still work)
var server = https.createServer({
  key: fs.readFileSync('privkey.pem', 'ascii'),
  cert: fs.readFileSync('cert.pem', 'ascii') // a PEM containing ONLY the SERVER certificate
});
// CORRECT (should always work)
var server = https.createServer({
  key: fs.readFileSync('privkey.pem', 'ascii'),
  cert: fs.readFileSync('fullchain.pem', 'ascii') // a PEM containing the SERVER and ALL INTERMEDIATES
});

Antwoord 7, autoriteit 3%

U kunt dit mogelijk doen door de verzoekopties zoals hieronder aan te passen. Als u een zelfondertekend certificaat of een ontbrekende tussenpersoon gebruikt, zal het instellen van strictSSL op false het aanvraagpakket niet dwingen om het certificaat te valideren.

var options = {
   host: 'jira.example.com',
   path: '/secure/attachment/206906/update.xlsx',
   strictSSL: false
}

Antwoord 8, autoriteit 3%

Een andere manier om dit op te lossen is om de volgende module te gebruiken.

node_extra_ca_certs_mozilla_bundle

Deze module kan werken zonder enige codewijziging door een PEM-bestand te genereren dat alle root- en intermediate certificaten bevat die door Mozilla worden vertrouwd. U kunt de volgende omgevingsvariabele gebruiken (Works with Nodejs v7.3+),

NODE_EXTRA_CA_CERTS

Om het PEM-bestand te genereren voor gebruik met de bovenstaande omgevingsvariabele. U kunt de module installeren met:

npm install --save node_extra_ca_certs_mozilla_bundle

en start vervolgens uw knooppuntscript met een omgevingsvariabele.

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

Andere manieren om het gegenereerde PEM-bestand te gebruiken zijn beschikbaar op:

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

OPMERKING: ik ben de auteur van de bovenstaande module.


Antwoord 9

GoDaddy SSL CC-certificaat

Ik heb dit meegemaakt toen ik verbinding probeerde te maken met onze backend API-server met een GoDaddy-certificaat en hier is de code die ik heb gebruikt om het probleem op te lossen.

var rootCas = require('ssl-root-cas/latest').create();
rootCas
  .addFile(path.join(__dirname, '../config/ssl/gd_bundle-g2-g1.crt'))
  ;
// will work with all https requests will all libraries (i.e. request.js)
require('https').globalAgent.options.ca = rootCas;

PS:

Gebruik het gebundelde certificaat en vergeet niet de bibliotheek npm install ssl-root-cas

te installeren


Antwoord 10

Dit werkte voor mij => agent toevoegen en ‘rejectUnauthorized’ ingesteld op false

const https = require('https'); //Add This
const bindingGridData = async () => {
  const url = `your URL-Here`;
  const request = new Request(url, {
    method: 'GET',
    headers: new Headers({
      Authorization: `Your Token If Any`,
      'Content-Type': 'application/json',
    }),
    //Add The Below
    agent: new https.Agent({
      rejectUnauthorized: false,
    }),
  });
  return await fetch(request)
    .then((response: any) => {
      return response.json();
    })
    .then((response: any) => {
      console.log('response is', response);
      return response;
    })
    .catch((err: any) => {
      console.log('This is Error', err);
      return;
    });
};

Antwoord 11

U kunt certificaatcontrole wereldwijd uitschakelen – ongeacht welk pakket u gebruikt voor het maken van verzoeken – als volgt:

// Disable certificate errors globally
// (ES6 imports (eg typescript))
//
import * as https from 'https'
https.globalAgent.options.rejectUnauthorized = false

Of

// Disable certificate errors globally
// (vanilla nodejs)
//
require('https').globalAgent.options.rejectUnauthorized = false

Natuurlijk moet u dit niet doen – maar het is zeker handig voor foutopsporing en / of zeer basiscripting waarbij u absoluut niet geeft om certificaten die correct zijn gevalideerd.


Antwoord 12

Ik heb een paar dagen terug geconfronteerd en dit is de benadering die ik volgde en het werkt voor mij.

Voor mij gebeurde dit toen ik de gegevens probeerde op te halen met behulp van axios of fetch-bibliotheken, omdat ik onder een bedrijfsfirewall ben, dus we hadden bepaalde specifieke certificaten die knooppunt JS Certificate Store niet in staat was om naar toe te wijzen.

Dus voor mijn loclahost volgde ik deze aanpak.
Ik heb een map in mijn project gemaakt en hield de hele keten van certificaten in de map en in mijn scripts voor Dev-Server (Package.json ) Ik heb dit toegevoegd aan Server Script, zodat knooppunt JS naar de pad.

"dev-server":set NODE_EXTRA_CA_CERTS=certificates/certs-bundle.crt

Voor mijn servers (verschillende omgevingen) heb ik een nieuwe omgevingsvariabele gecreëerd zoals hieronder en heeft het toegevoegd. Ik gebruikte OpenShift, maar ik denk dat het concept ook hetzelfde zal zijn voor anderen.

"name":NODE_EXTRA_CA_CERTS
"value":certificates/certs-bundle.crt

Ik heb geen certificaat in mijn geval gegenereerd, omdat de hele keten van certificaten al voor mij beschikbaar was.


Antwoord 13

Ik heb een zeer zeldzaam geval ontmoet, maar hopelijk zou het kunnen helpen aan iemand: een proxy-service heeft gemaakt, die verzoeken om een ​​andere dienstverlening. En elke fout van elk verzoek was “niet in staat om het eerste certificaat te verifiëren”, zelfs toen ik alle verwachte certificaten heeft toegevoegd.

De reden was vrij eenvoudig – ik heb per ongeluk ook de kop van de “host” opnieuw verzonden.
Zorg ervoor dat u geen “host” -kop expliciet verlaagt.


Antwoord 14

Ik was in staat om certificatenketen via browsers zoals Mozilla of Chrome te krijgen.

  1. Open Website, ga naar certificaatinstellingen van de webpagina en downloadcertificatenketen als bestandsnamen (First-CHINE.PEM, tweede-keten. PEM), moet in PEM-formaat zijn zoals
----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
......
-----END CERTIFICATE-----
----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
......
-----END CERTIFICATE-----
  1. Dan in uw Nodejs-code, heb ik het op typoscript, ik heb 2 CAS toegevoegd omdat ik 2 Webserver-aanvragen
  2. heb

import https from 'https'
import cas from 'ssl-root-cas'

……

interface CaList extends Buffer {
  addFile(file: string): Buffer[]
 }
 const caList = cas.create() as CaList
 caList.addFile(process.env.PROJECT_PATH + 'certs/first-chain.pem')
 caList.addFile(process.env.PROJECT_PATH + 'certs/second-chain.pem')

Dan, omdat ik WSSSHOSS-verbinding moet maken, voeg ik agent toe met lijst van nieuw CAS om aan te vragen

this.client.connect(KtUrl, undefined, undefined, undefined, {
    agent: new https.Agent({
      ca: caList
    })
})

moest ook definitiebestand toevoegen voor SSL-root-cas bestandsnaam SSL-root-cas.d.ts zodat typescript niet klagen

declare module 'ssl-root-cas' {
  function create(): string | Buffer | (string | Buffer)[] | undefined
}

Antwoord 15

Stel dit in in dev env:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';


Antwoord 16

Ik gebruikte de nodemailer npm-module. De onderstaande code heeft het probleem opgelost

    tls: {
     // do not fail on invalid certs
     rejectUnauthorized: false
     }

Other episodes