unable to verify the first certificate
Łańcuch certyfikatów jest niekompletny.
Oznacza to, że serwer sieciowy, z którym się łączysz, jest źle skonfigurowany i nie zawiera certyfikatu pośredniego w łańcuchu certyfikatów, który do Ciebie wysłał.
Łańcuch certyfikatów
Najprawdopodobniej wygląda to następująco:
- Certyfikat serwera - przechowuje certyfikat podpisany przez pośrednika.
- Certyfikat pośredni - przechowuje certyfikat podpisany przez administratora.
- Certyfikat główny - przechowuje certyfikat z podpisem własnym.
Certyfikat pośredni powinien być zainstalowany na serwerze wraz z certyfikatem serwera.
Certyfikaty główne są wbudowane w aplikacje, przeglądarki i systemy operacyjne.
Aplikacja obsługująca certyfikat musi wysłać cały łańcuch, czyli sam certyfikat serwera i wszystkie pośredniki. Certyfikat główny powinien być znany klientowi.
Odtwórz problem
Przejdź do https://incomplete-chain.badssl.com za pomocą przeglądarki.
Nie pokazuje żadnego błędu (kłódka w pasku adresu jest zielona).
Dzieje się tak, ponieważ przeglądarki zwykle uzupełniają łańcuch, jeśli nie jest on wysyłany z serwera.
Teraz połącz się z https://incomplete-chain.badssl.com za pomocą Node:
const axios = require('axios');
axios.get('https://incomplete-chain.badssl.com')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Dzienniki: „ Błąd: nie można zweryfikować pierwszego certyfikatu ”.
Rozwiązanie
Musisz samodzielnie uzupełnić łańcuch certyfikatów.
Aby to zrobić:
1: W takim razie musisz zdobyć brakujący certyfikat pośredni w .pem
formacie
2a: rozszerz wbudowany magazyn certyfikatów Node za pomocą NODE_EXTRA_CA_CERTS
,
2b: lub przekaż własny pakiet certyfikatów (pośrednie i root) za pomocą ca
opcji.
1. Jak uzyskać certyfikat pośredni?
Używanie openssl
(dostarczane z Git dla Windows ).
Zapisz szczegóły certyfikatu zdalnego serwera:
openssl s_client -connect incomplete-chain.badssl.com:443 -servername incomplete-chain.badssl.com | tee logcertfile
Poszukujemy wystawcy (certyfikat pośredni to wystawca / podpisujący certyfikat serwera):
openssl x509 -in logcertfile -noout -text | grep -i "issuer"
Powinien dać Ci identyfikator URI certyfikatu podpisującego. Pobierz to:
curl --output intermediate.crt http:
Na koniec przekonwertuj go na .pem
:
openssl x509 -inform DER -in intermediate.crt -out intermediate.pem -text
2a. NODE_EXTRA_CERTS
Używam cross-env do ustawiania zmiennych środowiskowych w package.json
pliku:
"start": "cross-env NODE_EXTRA_CA_CERTS=\"C:\\Users\\USERNAME\\Desktop\\ssl-connect\\intermediate.pem\" node index.js"
2b. ca
opcja
Ta opcja spowoduje nadpisanie wbudowanych głównych urzędów certyfikacji węzła.
Dlatego musimy stworzyć własny główny urząd certyfikacji. Użyj ssl-root-cas .
Następnie utwórz niestandardowego https
agenta skonfigurowanego za pomocą naszego pakietu certyfikatów (root i pośredni). Przekaż tego agenta axios
podczas składania wniosku.
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);
});
Zamiast tworzyć niestandardowego https
agenta i przekazywać go axios
, możesz umieścić certyfikaty w https
globalnym agencie:
https.globalAgent.options.ca = rootCas;
Zasoby:
- https://levelup.gitconnected.com/how-to-resolve-certificate-errors-in-nodejs-app-involving-ssl-calls-781ce48daded
- https://www.npmjs.com/package/ssl-root-cas
- https://github.com/nodejs/node/issues/16336
- https://www.namecheap.com/support/knowledgebase/article.aspx/9605/69/how-to-check-ca-chain-installation
- /superuser/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file/
- Jak przekonwertować .crt na .pem