node.jsssl

Node TLS Error: ca md too weak, when making request with Axios


I have a problem when I am making a request with Axios in node getting Error: ca md too weak.

I am sending .pfx file and password for the pfx certificate file. I can easily access API using Postman and sending pfx certificate and password, but making a request with Axios in node js (v. 18.0) I get Error: ca md too weak.

I don't want to downgrade Node version and using: process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; also doesn't help.

Also to connect to the server I have to use VPN and this error pops up even if I haven't turned on VPN.

Is it possible to bypass this check, so I can send a request as I do in the Postman?

Here is a code example:

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

Here is the error:

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)

Solution

  • TLDR: jump to end if you don't care about understanding

    rejectUnauthorized directs nodejs to accept (some) invalid certs used by the server instead of aborting the connection, but this error is occurring on your own client cert/chain not that of the server. (That's why it can occur even without the VPN you need for an actual connection.) The "CA_MD_TOO_WEAK" check occurs in modern versions of OpenSSL (1.1.0 up) but can vary depending on how the OpenSSL was built, thus for nodejs it also depends whether your nodejs was built to use its own embedded OpenSSL (usual on Windows) or one already provided on the system where it is installed (usual on Linux).

    You can look at the signature algorithms(s) used in your cert chain with openssl if you have (or get) it on this machine or you (may, can, and do) copy the pfx to a machine where ditto. First do

    openssl pkcs12 -in yourpfxfile -nokeys >temp0
    

    and look at temp0; it should contain one or more blocks each consisting of a subject= line, an issuer= line, a -----BEGIN CERTIFICATE----- line, several lines of base64, and an -----END CERTIFICATE----- line. (Likely there are also Bag Attributes: lines optionally followed by indented lines; ignore those.)

    If there is only one block and it has the same value for subject and issuer, then your error should not have happened, because the cert is selfsigned and OpenSSL should not be checking signature strength on selfsigned cert. Otherwise, do

    openssl x509 -in temp0 -noout -text -certopt no_pubkey,no_sigdump,no_extensions
    

    and you should get a few lines of output that includes signatureAlgorithm: x where x is of the form {hash}withRSAEncryption ecdsa_with_{hash} dsa-with-{hash} or dsaWith{hash}. If {hash} is MD5, the signature on your certificate is weak and doesn't provide the security it claims -- although in your situation, if the server accepts it in spite of this weakness, it's probably not your problem.

    If the first (leaf) cert is not selfsigned (subject not same as issuer) and its signature algorithm does not use MD5, either

    1. the OpenSSL used by your nodejs is set to a higher than usual 'security level' -- this is not likely for a nodejs that has embedded OpenSSL but more plausible for a system-provided one, especially on security-focussed systems like RedHat 8; or

    2. the problem is with a cert other than the first one (i.e. a CA cert), but this shouldn't occur if your cert(s) are from a properly-run CA because such a CA should never have a higher CA cert signed with a weaker key or signature algorithm than the leaf cert, except the selfsigned root whose signature doesn't matter, and isn't checked so it wouldn't cause your error. However, if you want, break each block other than the first into a separate file, and repeat the openssl x509 procedure above on each except if the last one has subject and issuer the same don't check it because it is the selfsigned root cert.

    Anyway, workaround: add to your https-Agent options ciphers: "DEFAULT:@SECLEVEL=0". This should turn off several checks designed to prevent insecure SSL/TLS connections, including the one relevant here; as a result, if you use this code to process data of any importance, it may be at higher risk depending on what the server does.