unable to verify the first certificate
Chuỗi chứng chỉ không đầy đủ.
Điều đó có nghĩa là máy chủ web bạn đang kết nối bị định cấu hình sai và không bao gồm chứng chỉ trung gian trong chuỗi chứng chỉ mà nó gửi cho bạn.
Chuỗi chứng chỉ
Nó rất có thể trông như sau:
- Chứng chỉ máy chủ - lưu trữ chứng chỉ được ký bởi trung gian.
- Chứng chỉ trung gian - lưu trữ một chứng chỉ được ký bởi root.
- Chứng chỉ gốc - lưu trữ chứng chỉ tự ký.
Chứng chỉ trung gian nên được cài đặt trên máy chủ, cùng với chứng chỉ máy chủ.
Chứng chỉ gốc được nhúng vào các ứng dụng phần mềm, trình duyệt và hệ điều hành.
Ứng dụng phục vụ chứng chỉ phải gửi chuỗi hoàn chỉnh, điều này có nghĩa là chính chứng chỉ máy chủ và tất cả các trung gian. Chứng chỉ gốc được cho là do khách hàng biết.
Tái tạo vấn đề
Truy cập https://incomplete-chain.badssl.com bằng trình duyệt của bạn.
Nó không hiển thị bất kỳ lỗi nào (ổ khóa trong thanh địa chỉ là màu xanh lá cây).
Đó là bởi vì các trình duyệt có xu hướng hoàn thành chuỗi nếu nó không được gửi từ máy chủ.
Bây giờ, kết nối với https://incomplete-chain.badssl.com bằng Node:
// 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);
});
Nhật ký: " Lỗi: không thể xác minh chứng chỉ đầu tiên ".
Giải pháp
Bạn cần phải tự hoàn thành chuỗi chứng chỉ.
Để làm việc đó:
1: Bạn cần lấy chứng chỉ trung gian bị thiếu ở .pem
định dạng, sau đó
2a: mở rộng kho chứng chỉ tích hợp của Node bằng cách sử dụng NODE_EXTRA_CA_CERTS
,
2b: hoặc vượt qua gói chứng chỉ của riêng bạn (trung gian và root) bằng cách sử dụng ca
tùy chọn.
1. Làm thế nào để tôi có được chứng chỉ trung gian?
Sử dụng openssl
(đi kèm với Git cho Windows ).
Lưu chi tiết chứng chỉ của máy chủ từ xa:
openssl s_client -connect incomplete-chain.badssl.com:443 -servername incomplete-chain.badssl.com | tee logcertfile
Chúng tôi đang tìm kiếm nhà phát hành (chứng chỉ trung gian là nhà phát hành / người ký chứng chỉ máy chủ):
openssl x509 -in logcertfile -noout -text | grep -i "issuer"
Nó sẽ cung cấp cho bạn URI của chứng chỉ ký. Tải xuống:
curl --output intermediate.crt http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
Cuối cùng, chuyển đổi nó thành .pem
:
openssl x509 -inform DER -in intermediate.crt -out intermediate.pem -text
2a. NODE_EXTRA_CERTS
Tôi đang sử dụng cross-env để đặt các biến môi trường trong package.json
tệp:
"start": "cross-env NODE_EXTRA_CA_CERTS=\"C:\\Users\\USERNAME\\Desktop\\ssl-connect\\intermediate.pem\" node index.js"
2b. ca
Lựa chọn
Tùy chọn này sẽ ghi đè lên các CA gốc tích hợp của Node.
Đó là lý do tại sao chúng ta cần tạo CA gốc của mình. Sử dụng ssl-root-cas .
Sau đó, tạo một https
tác nhân tùy chỉnh được cấu hình với gói chứng chỉ của chúng tôi (gốc và trung gian). Thông qua đại lý này axios
khi thực hiện yêu cầu.
// 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);
});
Thay vì tạo một https
tác nhân tùy chỉnh và chuyển nó đến axios
, bạn có thể đặt các chứng nhận trên https
tác nhân toàn cầu:
// Applies to ALL requests (whether using https directly or the request module)
https.globalAgent.options.ca = rootCas;
Tài nguyên:
- https://levelup.gitconnected.com/how-to-resolve-certert-errors-in-nodejs-app-involve-ssl-calls-781ce48daded
- https://www.npmjs.com/package/ssl-root-cas
- https://github.com/nodejs/node/issues/16336
- https://www.namecheap.com/support/ledgeledridease/article.aspx/9605/69/how-to-check-ca-chain-installation
- /superuser/97201/how-to-save-a-remote-server-ssl-certert-locally-as-a-file/
- Cách chuyển đổi .crt sang .pem