Hata: nodejs'deki ilk sertifika doğrulanamıyor


142

Bir url kullanarak jira sunucusundan bir dosya indirmeye çalışıyorum ama bir hata alıyorum. Hatayı doğrulamak için koda sertifika nasıl eklenir:

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)

Nodejs kodum:

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);

    });
});

bunu çözebildin mi?
sharad jain

1
sertifika doğrulamasını devre dışı bırakmak gibi başka bir prosedür kullandım ve bitti
Labeo

biraz daha detaylandırır mısın? Bu benim için gerçekten yardımcı olacak
sharad jain

Reddetmemiz gereken sertifikanın doğrulanması için aşağıdaki cevaba bakınUnauthorized
Labeo

Yanıtlar:


120

Uygun kök sertifikayı eklemeyi deneyin

Bu her zaman, yalnızca son çare olarak kullanılması gereken yetkisiz uç noktaları körü körüne kabul etmekten çok daha güvenli bir seçenek olacaktır.

Bu, eklemek kadar basit olabilir

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

uygulamanıza.

SSL Kök CA'lar npm paketi (burada kullanılan) bu sorunla ilgili çok yararlı bir pakettir.


9
Bu cevap, SSL'nin tüm faydasını devre dışı bırakmak yerine sorunu gerçekten çözdüğü için çoğu durumda kullanılmalıdır.
mikemaccana

12
Ssl-root-cas modülünde de belirtildiği gibi README, bu sorunun en yaygın nedenlerinden biri, sertifikanızın ara CA sertifikalarını katıştırmamasıdır. Başka bir şey denemeden önce sertifikanızı düzeltmeyi deneyin;)
Laurent VB

SSL-root-cas paketine bile ihtiyacınız olmayabilir. GlobalAgents.option.cert'i tam zincir sertifikasına ayarlayın. Sorunumu çözen buydu.
smartexpert

1
mkcert bir "tam zincir" sertifikası oluşturmaz. Sertifikanızı $(mkcert -CAROOT)/rootCA.pemyeni bir sertifika dosyasında bulunan kök sertifika ile birleştirmeniz ve https.globalAgent.options.ca = fs.readFileSync('fullchain.pem')Bkz. Github.com/FiloSottile/mkcert/issues/76
Frosty Z

Güvenlik için, ssl-root-casnpm modülünün mozilla.org kodlu git.coolaj86.com/coolaj86/ssl-root-cas.js/src/branch/master/… için bir isteği vardır . Muhtemelen güvenli çünkü Mozilla ama bir saldırı vektörü gibi görünüyor.
Avindra Goolcharan

62

Tüm isteklerinizi güvensiz hale getirecek başka bir kirli hack:

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0

8
Bu, Labeo'nun yukarıdaki yanıtından farklı değil , aynı derecede tehlikeli görünüyor.
ocramot

4
Farklıdır, env değişkeni kaynak kodun dışında ayarlanabileceği için herhangi bir kodlama değişikliği gerektirmez.
jzacharuk

1
Bu cevap tehlikelidir. TLS'nin sağladığı herhangi bir güvenliği devre dışı bırakıyorsunuz.
Flimm

2
Bu benim için çalıştı, çok yardımcı oldu. Benim durumumda, sadece localhost ile konuşuyorum , bu yüzden güvenlik sorun değil.
Mike S

Sadece localhost'u test etmek için gerçekten iyi. Testlerinizden sonra çıkardığınızdan emin olun.
Nico

44

nodejs'deki ilk sertifikayı doğrulayamamak için yetkisiz reddetmek gerekir

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

130
Bu cevap tehlikelidir. Diğeri daha güvenli.
mikemaccana

3
Bunu yaparak, SSL tarafından sağlanan güvenliği kaldırmış olursunuz, bu nedenle yalnızca geliştirme için kullanılmalıdır.
Sylvain

11
Sertifikaları kontrol etmemek, diğer tarafın kimliğinden emin olamayacağınız ve bu nedenle sahte bir ana makineye tabi olabileceğiniz anlamına gelir. Sertifikaları kontrol etmeseniz bile, yine de (kolayca) gözetlenemeyen şifreli iletişim elde edersiniz. Yani bu satırı eklemek ne SSL'nin "güvenliğini kaldırmaz" ne de başka bir yorumcunun dediği gibi "[] SSL'nin tüm avantajını devre dışı bırak".
Bob Pollack

4
SSL doğrulamasını devre dışı bırakmak herhangi bir soruna çözüm DEĞİLDİR. :-)
Siddhu

9
Bu, düğüm isteği kitaplığını kullanıyorsanız çalışır. Ben hangisiyim. Ve teşekkür ederim, acil gelişim ihtiyacımı çözüyor.
Alan

29

İndirmeye çalıştığınız sunucu kötü yapılandırılmış olabilir. Tarayıcınızda çalışsa bile, önbelleği boş olan bir istemcinin doğrulanması için gereken zincirdeki tüm genel sertifikaları içermiyor olabilir.

Siteyi SSLlabs aracında kontrol etmenizi öneririm: https://www.ssllabs.com/ssltest/

Bu hatayı arayın:

Bu sunucunun sertifika zinciri eksik.

Ve bu:

Zincir sorunları ......... Eksik


DigiCert Inc. tarafından yetkilendirilmiş sertifikam için bu sorunu (Zincir sorunları ......... Eksik) alıyorum, bunu düzeltmek için prosedür nedir?
imarchuang

@imarchuang Kısacası, sunucunuzun yalnızca etki alanınız için değil, aynı zamanda ara sertifikaları da sunması gerekir. Bu yoruma daha fazla ayrıntı sığdıramıyorum ama umarım bu sizi doğru yöne yönlendirmek için yeterlidir.
Flimm

çok teşekkürler, kök sertifikasını da
tarayarak anladık

Teşekkürler! Chrome ve firefox'ta mükemmel çalışmasına rağmen elektron uygulamasında çalışmadığı halde sertifikamın eksik olduğunu keşfettim ve cat domainname.crt domainname.ca-bundle > domainname-ssl-bundle.crt
nginx'de

26

unable to verify the first certificate

Sertifika zinciri eksik.

Bu, bağlandığınız web sunucusunun yanlış yapılandırıldığı ve size gönderdiği sertifika zincirine ara sertifikayı dahil etmediği anlamına gelir.

Sertifika zinciri

Büyük olasılıkla aşağıdaki gibi görünür:

  1. Sunucu sertifikası - aracı tarafından imzalanmış bir sertifikayı depolar.
  2. Ara sertifika - kök tarafından imzalanmış bir sertifikayı saklar.
  3. Kök sertifika - kendinden imzalı bir sertifika depolar.

Ara sertifika, sunucu sertifikasıyla birlikte sunucuya yüklenmelidir.
Kök sertifikalar yazılım uygulamalarına, tarayıcılara ve işletim sistemlerine yerleştirilmiştir.

Sertifikaya hizmet eden uygulamanın tüm zinciri göndermesi gerekir, bu da sunucu sertifikasının kendisi ve tüm ara maddeler anlamına gelir. Kök sertifikanın istemci tarafından bilinmesi gerekiyor.

Sorunu yeniden yaratın

Tarayıcınızı kullanarak https://incomplete-chain.badssl.com adresine gidin .

Herhangi bir hata göstermez (adres çubuğundaki asma kilit yeşildir).
Bunun nedeni , sunucudan gönderilmezse tarayıcıların zinciri tamamlama eğiliminde olmasıdır .

Şimdi Düğümü kullanarak https://incomplete-chain.badssl.com adresine bağlanın :

// 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);
  });

Günlükler: " Hata: ilk sertifika doğrulanamıyor ".

Çözüm

Sertifika zincirini kendiniz tamamlamanız gerekir.

Bunu yapmak için:

1: Eksik ara sertifikayı .pemformatta almanız gerekir , ardından

2a: Düğümün yerleşik sertifika deposunu NODE_EXTRA_CA_CERTS,

2b: veya caseçeneği kullanarak kendi sertifika paketinizi (ara ürünler ve kök) geçirin .

1. Ara sertifikayı nasıl alırım?

Kullanarak openssl( Windows için Git ile birlikte gelir ).

Uzak sunucunun sertifika ayrıntılarını kaydedin:

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

Sertifikayı veren kişiyi arıyoruz (ara sertifika, sunucu sertifikasını veren / imzalayan kişidir):

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

İmza sertifikasının URI'sini size vermelidir. İndir:

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

Son olarak, şuna dönüştürün .pem:

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

2a. NODE_EXTRA_CERTS

Dosyadaki ortam değişkenlerini ayarlamak için ortamlar arası kullanıyorum package.json:

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

2b. caseçenek

Bu seçenek, Düğümün yerleşik kök CA'larının üzerine yazacak.

Bu yüzden kendi kök CA'mızı oluşturmamız gerekiyor. Ssl-root-cas kullanın .

Ardından, httpssertifika paketimizle (kök ve ara) yapılandırılmış özel bir aracı oluşturun . axiosTalepte bulunurken bu temsilciye iletin.

// 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);
  });

Özel bir httpsaracı oluşturup bunu iletmek axiosyerine, sertifikaları httpsglobal temsilciye yerleştirebilirsiniz:

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

Kaynaklar:

  1. https://levelup.gitconnected.com/how-to-resolve-certificate-errors-in-nodejs-app-involving-ssl-calls-781ce48daded
  2. https://www.npmjs.com/package/ssl-root-cas
  3. https://github.com/nodejs/node/issues/16336
  4. https://www.namecheap.com/support/knowledgebase/article.aspx/9605/69/how-to-check-ca-chain-installation
  5. /superuser/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file/
  6. .Crt'yi .pem'e dönüştürme

Çok detaylı açıklama.
Yedi

1
Kesinlikle muhteşem! Benim için çalışmadı, ama ne detay!
Tom Chadaravicius

6

Bu aslında benim için https://www.npmjs.com/package/ssl-root-cas adresinden çözdü.

// 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
});

1
Ek kitaplıklar gerektirmediği ve basit olduğu için en iyi çözüm budur
Martin Schneider

4

Aşağıdaki gibi istek seçeneklerini değiştirerek bunu yapabilirsiniz. Kendinden imzalı bir sertifika veya eksik bir aracı kullanıyorsanız, tightSSL'yi false olarak ayarlamak, sertifikayı doğrulamak için istek paketini zorlamaz.

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

Bu sorunumu çözdü, 'http' yerine 'istek' modülünü kullanıyorum. Teşekkürler!
Bruno Nunes

2

GoDaddy SSL CCertifikası

Bunu GoDaddy sertifikası ile arka uç API sunucumuza bağlanmaya çalışırken yaşadım ve işte sorunu çözmek için kullandığım kod.

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;

Not:

Birlikte verilen sertifikayı kullanın ve kitaplığı yüklemeyi unutmayın npm install ssl-root-cas


1
bu benim için çalıştı, ancak içe aktarırken "ssl-root-cas / latest" yerine "ssl-root-cas" kullanmak zorunda kaldım.
krishnan

2

Bu Benim İçin Çalıştı => aracı ekleme ve 'rejectUnauthorized' yanlış olarak ayarlandı

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;
    });
};


1

Bunu çözmek için başka bir yaklaşım aşağıdaki modülü kullanmaktır.

node_extra_ca_certs_mozilla_bundle

Bu modül, Mozilla'nın güvendiği tüm kök ve ara sertifikaları içeren bir PEM dosyası oluşturarak herhangi bir kod değişikliği yapmadan çalışabilir. Aşağıdaki ortam değişkenini kullanabilirsiniz (Nodejs v7.3 + ile çalışır),

NODE_EXTRA_CA_CERTS

Yukarıdaki ortam değişkeniyle kullanmak üzere PEM dosyasını oluşturmak için. Modülü kullanarak kurabilirsiniz:

npm install --save node_extra_ca_certs_mozilla_bundle

ve sonra bir ortam değişkeniyle düğüm komut dosyanızı başlatın.

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

Oluşturulan PEM dosyasını kullanmanın diğer yolları şu adreste mevcuttur:

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

NOT: Yukarıdaki modülün yazarıyım.


-3

Nodemailer npm modülünü kullanıyordum. Aşağıdaki kod sorunu çözdü

     tls: {
     // do not fail on invalid certs
     rejectUnauthorized: false
     }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.