当我在节点中使用 Axios 发出请求时遇到问题,出现错误:ca md 太弱。
我正在发送 .pfx 文件和 pfx 证书文件的密码。 我可以使用 Postman 轻松访问 API 并发送 pfx 证书和密码,但在 Node js (v. 18.0) 中使用 Axios 发出请求时,我收到错误:ca md 太弱。
我不想降级 Node 版本并使用: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
这是错误:
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)
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
然后看temp0
;它应该包含一个或多个块,每个块由一行
subject=
行、一行
issuer=
行、一行
-----BEGIN CERTIFICATE-----
行、几行 base64 行和一行
-----END CERTIFICATE-----
行组成。 (可能还有
Bag Attributes:
行,可选地后跟缩进行;忽略这些。)如果只有一个块,并且
subject
和
issuer
具有相同的值,那么您的错误不应该发生,因为证书是自签名的,并且 OpenSSL 不应该检查自签名证书上的签名强度。否则,做
openssl x509 -in temp0 -noout -text -certopt no_pubkey,no_sigdump,no_extensions
并且您应该得到几行输出,其中包括 signatureAlgorithm: x
,其中
x
的形式为
{hash}withRSAEncryption ecdsa_with_{hash} dsa-with-{hash} or dsaWith{hash}
。如果
{hash}
是 MD5,则您的证书上的签名很弱,并且不能提供其声称的安全性 - 尽管在您的情况下,如果服务器尽管存在此弱点但仍接受它,则可能不是您的问题。如果第一个(叶)证书不是自签名的(
subject
与
issuer
不同)并且其签名算法也不使用MD5
或 签名算法进行签名,但自签名根除外,其签名无关紧要,并且不进行检查,因此不会导致您的错误。但是,如果您愿意,可以将第一个块以外的每个块分解为一个单独的文件,并对每个 除了
重复上面的
openssl x509
过程,如果最后一个有 subject
和
issuer
则不要检查它因为它是自签名根证书。
解决方法:添加到您的 https-Agent 选项ciphers: "DEFAULT:@SECLEVEL=0"
。这应该会关闭旨在防止不安全 SSL/TLS 连接的多项检查,包括此处相关的检查;因此,如果您使用此代码来处理任何重要的数据,它可能面临更高的风险,具体取决于服务器的行为。
import tls from 'tls'
const createSecureContext = tls.createSecureContext;
tls.createSecureContext = function(...args) {
console.log('Custom tls.connect called');
return createSecureContext.apply(this, {...args, ciphers:"DEFAULT:@SECLEVEL=0"});
};