我正在使用CLI工具来构建具有很酷上传功能的混合移动应用程序,因此我可以在设备上测试应用程序而无需通过应用程序商店(它是ionic-cli).但是,在我的公司,像许多其他公司一样,TLS请求使用公司自己的自定义CA证书重新签名,我在我的机器上有钥匙串(OS X).但是,nodejs不使用密钥链来获取其信任的CA列表.我不控制ionic-cli应用程序,所以我不能简单地将{ca:}属性传递给https模块.我还可以看到这是我无法控制的任何节点应用程序的问题.是否可以告诉nodejs信任CA?
我不确定这是属于信息安全还是任何其他交易所......
小智 68
Node.js 7.3.0(以及LTS版本6.10.0和4.8.0)NODE_EXTRA_CA_CERTS为您添加了环境变量以传递CA证书文件.它比使用禁用证书验证更安全NODE_TLS_REJECT_UNAUTHORIZED.
$ export NODE_EXTRA_CA_CERTS=[your CA certificate file path]
Mag*_*ode 45
您可以指定命令行选项来告诉节点使用系统 CA 存储:
node --use-openssl-ca
或者,如果您自己不直接运行节点 CLI,则可以将其指定为环境变量:
NODE_OPTIONS=--use-openssl-ca
我知道有两个npm模块可以在你控制应用程序时处理这个问题:
node-ssl-root-cas捆绑它自己的节点根CA副本,并且还可以将您自己的CA添加到信任中.它将证书放在https全局代理上,因此它只用于https模块,而不是纯tls连接.此外,如果使用自定义代理而不是全局代理,则需要执行额外的步骤.
syswide-cas从预定义的目录(例如/ etc/ssl/certs)加载证书,并使用节点内部API将它们与捆绑的根CA一起添加到受信任的CA列表中.无需使用该ca选项,因为它会全局更改,这会自动影响所有后续TLS调用.如果需要,还可以从其他目录/文件添加CA. 验证了它与节点0.10,节点5和节点6一起工作.
由于您不控制应用程序,您可以创建一个包装器脚本来启用syswide-cas(或node-ssl-root-cas)然后需要ionic-cli脚本:
require('syswide-cas'); // this adds your custom CAs in addition to bundled CAs
require('./path/to/real/script'); // this runs the actual script
除非您使用自定义 CA 证书编译自定义版本的 nodejs,否则目前这是不可能的。在有人提交 PR 并将其合并之前,严格的 CA 证书是 nodejs 的当前限制。这对其他人来说也是一个问题。
下面我有一些变通方法的副本,它们可能对某些人有帮助,但可能对 OP 没有帮助。
据我所知 OP 可以:
其他人,如果您控制有问题的 nodejs 应用程序,您将有更多选择。您当然可以在每个请求中指定 ca 证书。一些聪明的人在 github 问题https://github.com/nodejs/node/issues/4175 中分享了一些解决方法。我自己还没有尝试过任何这些,所以没有承诺,我只是分享我读过的东西。
DuBistKomisch 解释了如何让 nodejs 使用操作系统的 CA 证书:
我的解决方法是手动加载和解析系统 CA 证书。然后,按照请求文档的建议,在我们发出请求的任何地方使用 ca 选项传递它们。如果这适用于您的用例,我认为您也可以在全局代理上设置 ca 。
Run Code Online (Sandbox Code Playgroud)fs.readFileSync('/etc/ssl/certs/ca-certificates.crt') .toString() .split(/-----END CERTIFICATE-----\n?/) // may include an extra empty string at the end .filter(function (cert) { return cert !== ''; }) // effectively split after delimiter by adding it back .map(function (cert) { return cert + '-----END CERTIFICATE-----\n'; })
mwain 解释了如何全局设置 CA 证书,而不是针对每个 https 请求:
有类似的问题,有使用内部签名证书的内部应用程序。选择使用 https.globalAgent 并设置一组 CA,这些 CA 在配置中定义并在 env 基础上更新。
Run Code Online (Sandbox Code Playgroud)const trustedCa = [ '/etc/pki/tls/certs/ca-bundle.crt', '/path/to/custom/cert.crt' ]; https.globalAgent.options.ca = []; for (const ca of trustedCa) { https.globalAgent.options.ca.push(fs.readFileSync(ca)); }
有一个未记录的、看似稳定的 API 用于将证书附加到默认列表:
const tls = require('tls');
const secureContext = tls.createSecureContext();
// https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt
secureContext.context.addCACert(`-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----`);
const sock = tls.connect(443, 'host', { secureContext });
有关更多信息,请查看该主题的未解决问题:https : //github.com/nodejs/node/issues/27079
| 归档时间: | 
 | 
| 查看次数: | 43572 次 | 
| 最近记录: |