unable to verify the first certificate
证书链不完整。
这意味着您要连接的Web服务器配置错误,并且在发送给您的证书链中未包含中间证书。
证书链
它最可能如下所示:
- 服务器证书-存储由中间人签名的证书。
- 中间证书-存储由root签名的证书。
- 根证书-存储自签名证书。
中间证书应与服务器证书一起安装在服务器上。
根证书已嵌入到软件应用程序,浏览器和操作系统中。
提供证书的应用程序必须发送完整的链,这意味着服务器证书本身以及所有中间产品。客户端应该知道根证书。
重现问题
使用浏览器访问https://incomplete-chain.badssl.com。
它没有显示任何错误(地址栏中的挂锁为绿色)。
这是因为,如果不是从服务器发送的,浏览器往往会完成该链。
现在,使用Node 连接到https://incomplete-chain.badssl.com:
// 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);
});
记录:“ 错误:无法验证第一个证书 ”。
解
您需要自己完成证书链。
要做到这一点:
1:您需要以.pem
格式获取丢失的中间证书,然后
2a:使用扩展Node的内置证书存储NODE_EXTRA_CA_CERTS
,
2b:或使用ca
选项传递您自己的证书捆绑包(中间件和根)。
1.如何获得中间证书?
使用openssl
(适用于Windows的Git附带)。
保存远程服务器的证书详细信息:
openssl s_client -connect incomplete-chain.badssl.com:443 -servername incomplete-chain.badssl.com | tee logcertfile
我们正在寻找颁发者(中间证书是服务器证书的颁发者/签名者):
openssl x509 -in logcertfile -noout -text | grep -i "issuer"
它应该给您签名证书的URI。下载它:
curl --output intermediate.crt http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
最后,将其转换为.pem
:
openssl x509 -inform DER -in intermediate.crt -out intermediate.pem -text
2a。NODE_EXTRA_CERTS
我正在使用交叉环境在package.json
文件中设置环境变量:
"start": "cross-env NODE_EXTRA_CA_CERTS=\"C:\\Users\\USERNAME\\Desktop\\ssl-connect\\intermediate.pem\" node index.js"
2b。ca
选项
此选项将覆盖节点的内置根CA。
这就是为什么我们需要创建自己的根CA。使用ssl-root-cas。
然后,创建一个https
使用我们的证书捆绑包配置的自定义代理(根证书和中间证书)。axios
发出请求时,将此代理传递给。
// 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);
});
无需创建自定义https
代理并将其传递给axios
,您可以将证书放在https
全局代理上:
// Applies to ALL requests (whether using https directly or the request module)
https.globalAgent.options.ca = rootCas;
资源:
- 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/
- 如何将.crt转换为.pem