【问题标题】:NodeJs throws SSL error when connecting to Web API running on Windows server with SSL certificateNodeJs 在使用 SSL 证书连接到在 Windows 服务器上运行的 Web API 时抛出 SSL 错误
【发布时间】:2021-05-13 12:50:13
【问题描述】:

我在 Windows 上运行 Web API 服务器。它在 https 上使用证书和主机 Web API。

例如,当我在 chrome 浏览器中输入下面的 URL 时,它会将客户列表作为 JSON 数组提供。

https://windows-hostname.xyz.com/api/customers

此外,当我将此 URL 放入任何跨组织的机器上的 Chrome 浏览器中时,它可以正常工作并返回数据。它确实抛出证书错误 - 因为它使用的证书是公司证书颁发者颁发的有效证书。

但是,当我编写 Nodejs 程序来访问相同的 URL 时。 IT 向我抛出 SSL 错误

const superagent = require('superagent');
var baseUrl = 'https://windows-hostname.xyz.com';
superagent
    .get(baseUrl + "/api/customers")
    .set("accept", "application/json")
    .end(function(err, resp){
       // throws ERROR - err = Error: unable to get local issuer certificate at TLSSocket.onConnectSecure
    }

我在 “受信任的根证书颁发机构”下安装了证书(在 Windows 服务器上运行 MMC->添加/删除管理单元->在左侧窗格中选择证书->添加到右侧窗格->计算机帐户->) "

我可以右键单击证书并导出带有 .CER 扩展名的证书(BASE-64 编码)。我无法导出私钥。

我更改了上面的程序以使用这个导出的证书。然后它抛出我 错误:无法在 TLSSocket.onConnectSecure 获得本地颁发者证书

const superagent = require('superagent');
var ca = fs.readFileSync('exported.cer');
var baseUrl = 'https://windows-hostname.xyz.com';
superagent
    .get(baseUrl + "/api/customers")
    .set("accept", "application/json")
    .ca(ca)
    .end(function(err, resp){
       // throws ERROR - err = Error: unable to get local issuer certificate at TLSSocket.onConnectSecure 
    }

我的问题是如何使用这个导出的 .CER 文件并编写可以连接到这个 Web 应用程序而不会出现 SSL 错误的 nodejs 程序?

另外,我不能忽略证书错误

谢谢, 阿图尔

【问题讨论】:

  • 可能服务器没有发送所需的链证书,Chrome 等浏览器可以“填写”,但 nodejs 等软件不能。如果您拥有(或获得)OpenSSL,请尝试openssl s_client -connect $hostname:443 -CAfile exported.cer <NUL:(低于 1.1.1 添加-servername $hostname)并查看接近末尾的Verify return code 行。如果显示类似错误,请添加 -showcerts 以查看服务器实际发送的内容,然后 (1) 修复服务器或 (2) 从浏览器中提取丢失的证书或使用 AIA 获取它们较低证书中的数据,并添加到用于ca 的文件中。
  • PS:您在“受信任的根”(或其他任何地方)中的 CA 证书副本不应该也没有私钥是完全正确的,因此您无法导出它,因为它不是那里。您可以在 Windows 显示中看到其图标左侧没有黄色键(右侧只有一个圆形印章)。

标签: node.js ssl


【解决方案1】:

感谢@dave_thompson_085 的努力和帮助。 我可以解决这个问题。这并不难。基本上,当我将证书导出为 CER 文件(BASE - 64 编码)时,它不包括证书链中的所有证书。例如不包括颁发者证书。

因此,我创建了单个 exported.CER 文件,该文件连接了证书链中的所有证书 - 包括顶部的所有颁发者。

-----BEGIN CERTIFICATE-----
XXXXIszCCBpugAwIBAgITKQAANSmJkY5OfHmEGgAAAAA1AAAAAAAAAAABBBBBBBBB
YYYYMR33333333333333333333YD55555555555555555555LGQBGR11223344553
...
-----END CERTIFICATE-----
Bag Attributes: <Empty Attributes>
subject=DC = com, DC = xyz, DC = domain, CN = Company Root CA
issuer=DC = com, DC = xyz, DC = domain, CN = Company Root CA

-----BEGIN CERTIFICATE-----
XXXXYYYYYYYYYYwIBAgITKQAAN77777777777777777777TAN1111111111111111
YYYYMRMwEQYKCZImiZPyLG99999999999999999999ImiZPyLGQBGR11223344553
...
-----END CERTIFICATE-----
Bag Attributes: <Empty Attributes>
subject=DC = com, DC = xyz, DC = domain, CN = Issuer

issuer=DC = com, DC = xyz, DC = domain, CN = Company Root CA
-----BEGIN CERTIFICATE-----
XXXXYYYYYYYYYYwIBAgITKQAANSmJkY5OfHmEGgAAAAA1KTANBgkqhkiG9w0BAQsF
YYYYMRMwEQYKCZI00011111111111111111111111111111yLGQBGR11223344553
...
-----END CERTIFICATE-----

现在,当我拥有包含证书链中所有证书的 .CER 文件时,我的早期程序可以工作。

我们还可以使用以下 openssl 命令获取链中的所有证书。

 openssl s_client -connect windows-hostname.xyz.com:443  -showcerts

此命令提供 2 个证书而不是顶级证书。我不确定它是否仍然有效。

最简单的方法是右键单击并导出证书链中的所有证书并创建一个文件。

谢谢, 阿图尔

【讨论】:

    猜你喜欢
    • 2012-02-02
    • 2012-10-18
    • 2020-05-09
    • 2012-12-04
    • 1970-01-01
    • 2023-04-07
    • 2016-07-12
    • 1970-01-01
    • 2014-04-10
    相关资源
    最近更新 更多