使用 Axios 发出请求时,节点 TLS 错误:ca md 太弱

Ivi*_*ler 3 ssl node.js

当我在节点中使用 Axios 发出请求时遇到问题,出现错误:ca md 太弱。

我正在发送 .pfx 文件和 pfx 证书文件的密码。我可以使用 Postman 轻松访问 API 并发送 pfx 证书和密码,但在 Node js (v.18.0) 中使用 Axios 发出请求时出现错误:ca md 太弱。

我不想降级节点版本并使用:process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; 也没有帮助。

另外,要连接到服务器,我必须使用 VPN,即使我没有打开 VPN,也会弹出此错误。

是否可以绕过此检查,以便我可以像在 Postman 中那样发送请求?

这是一个代码示例:

agent = new https.Agent({
    pfx: fs.readFileSync((process.cwd() + "\\src\\sources\\KIISWSClient.pfx")),
    passphrase: 'password',
    rejectUnauthorized: false,
  });

  userKiisData = axios.post('https://ws-kiis.hlk.hr/AdeoMembersPublicService.svc/WSPublic/BasicData', {
    Username: "myusername",
    Role: "role"
  }, {
    auth: {
      username: "user",
      password: "mypassword"
    },
    httpsAgent: agent
  }
return userKiisData
Run Code Online (Sandbox Code Playgroud)

这是错误:

Error: ca md too weak
    at configSecureContext (node:internal/tls/secure-context:278:15)
    at Object.createSecureContext (node:_tls_common:113:3)
    at Object.connect (node:_tls_wrap:1622:48)
    at Agent.createConnection (node:https:142:22)
    at Agent.createSocket (node:_http_agent:343:26)
    at Agent.addRequest (node:_http_agent:294:10)
    at new ClientRequest (node:_http_client:311:16)
    at Object.request (node:https:352:10)
Run Code Online (Sandbox Code Playgroud)

dav*_*085 5

TLDR:如果您不关心理解,请跳到结尾

rejectUnauthorized指示 NodeJS 接受服务器使用的(某些)无效证书而不是中止连接,但此错误发生在您自己的客户端证书/链上,而不是服务器的客户端证书/链上。(这就是为什么即使没有实际连接所需的 VPN,它也会发生。)“CA_MD_TOO_WEAK”检查发生在现代版本的 OpenSSL(1.1.0 以上)中,但可能会根据 OpenSSL 的构建方式而有所不同,因此对于 Nodejs 来说还取决于您的nodejs是否构建为使用其自己的嵌入式OpenSSL(通常在Windows上)或安装它的系统上已经提供的OpenSSL(通常在Linux上)。

如果您在本机上拥有(或获取)了它,则可以使用 openssl 查看证书链中使用的签名算法,或者您(可以、可以并且确实)将 pfx 复制到同上的计算机。首先做

openssl pkcs12 -in yourpfxfile -nokeys >temp0
Run Code Online (Sandbox Code Playgroud)

并看看temp0;它应该包含一个或多个块,每个块由subject=一行、issuer=一行-----BEGIN CERTIFICATE-----、一行、几行 Base64 和一行组成-----END CERTIFICATE-----。(可能还有一些Bag Attributes:行可选地后跟缩进行;忽略这些行。)

如果只有一个块并且它的 和 具有相同的值subjectissuer那么您的错误应该不会发生,因为证书是自签名的,并且 OpenSSL 不应该检查自签名证书上的签名强度。否则,执行

openssl x509 -in temp0 -noout -text -certopt no_pubkey,no_sigdump,no_extensions
Run Code Online (Sandbox Code Playgroud)

您应该得到几行输出,其中包括form 的signatureAlgorithm: xwhere is 。如果是 MD5,则您的证书上的签名很弱,并且无法提供其声称的安全性 - 尽管在您的情况下,如果服务器尽管存在此弱点但仍接受它,则可能不是您的问题。x{hash}withRSAEncryption ecdsa_with_{hash} dsa-with-{hash} or dsaWith{hash}{hash}

如果第一个(叶)证书不是自签名的(subject与 不同issuer)并且其签名算法不使用 MD5,则

  1. 你的nodejs使用的OpenSSL被设置为比通常的“安全级别”更高——这对于嵌入OpenSSL的nodejs来说不太可能,但对于系统提供的系统来说更合理,特别是在像RedHat 8这样注重安全的系统上;或者

  2. 问题出在第一个证书以外的证书(即 CA 证书)上,但如果您的证书来自正确运行的 CA,则不会发生这种情况,因为这样的 CA 永远不应该有更高的 CA 证书签名比叶证书更弱的密钥签名算法,但自签名根除外,其签名无关紧要,并且不进行检查,因此不会导致错误。但是,如果您愿意,请将除第一个块之外的每个块分解为一个单独的文件,并对openssl x509每个块重复上述过程,除非最后一个块有subject并且issuer同样不检查它,因为它是自签名根证书。

无论如何,解决方法:添加到您的 https-Agent options ciphers: "DEFAULT:@SECLEVEL=0"。这应该会关闭多项旨在防止不安全 SSL/TLS 连接的检查,包括此处相关的检查;因此,如果您使用此代码来处理任何重要的数据,则可能会面临更高的风险,具体取决于服务器的操作。