Making Mutual SSL (mTLS) API Requests in Node.js

Making Mutual SSL (mTLS) API Requests in Node.js



Mutual TLS (mTLS) is a common security requirement in enterprise environments. Unlike regular HTTPS (where only the server is authenticated), mTLS requires both the client and the server to authenticate each other using certificates.

This guide focuses on using Node.js as a client to call an API protected by mutual TLS. It also covers a very common real-world problem:

  • Your Ops or Security team gives you a .jks file
  • JKS is designed for Java / Spring Boot
  • Node.js needs .key, .crt, and .pem files instead

We’ll walk through converting the JKS file and using it in Node.js step by step.


What Files Does Node.js Need for Mutual TLS?

To make an mTLS request from Node.js, you typically need:

  • client.key – your private key
  • client.crt – your client certificate
  • ca.pem – the Certificate Authority (CA) chain to trust the server

These are passed to Node’s HTTPS agent.


Step 1: Convert JKS to PKCS12 (.p12)

Java applications often use JKS keystores. The first step is converting it to PKCS12, which OpenSSL can work with.

keytool -importkeystore \
  -srckeystore your.jks \
  -srcstoretype JKS \
  -srcalias youralias \
  -destkeystore your.p12 \
  -deststoretype PKCS12

You’ll be prompted for the source and destination keystore passwords. After this step, you’ll have a .p12 file.


Step 2: Extract the Private Key

Extract the client private key from the PKCS12 file:

openssl pkcs12 \
  -in your.p12 \
  -nocerts \
  -nodes \
  -out client.key

⚠️ Keep this file secure. Do not commit it to source control.


Step 3: Extract the Client Certificate

openssl pkcs12 \
  -in your.p12 \
  -clcerts \
  -nokeys \
  -out client.crt

This is the certificate presented to the server during the TLS handshake.


Step 4: Extract the CA Certificates

openssl pkcs12 \
  -in your.p12 \
  -cacerts \
  -nokeys \
  -out ca.pem

This file allows Node.js to verify the server’s certificate.


Step 5: Store Certificates Securely (OpenShift / Kubernetes)

In containerized environments, certificates are usually stored as secrets. Here’s how to generate a Kubernetes/OpenShift secret YAML without applying it directly:

oc create secret generic mutual-tls-certs \
  --from-file=client.key \
  --from-file=client.crt \
  --from-file=ca.pem \
  --dry-run=client \
  -o yaml > mutual-tls-certs.yaml

This YAML can be safely committed and managed by GitOps tools such as Argo CD.


Step 6: Make an mTLS API Request in Node.js

volumeMounts:
- name: mutual-tls-certs
mountPath: /certs
readOnly: true
volumes:
- name: mutual-tls-certs
secret:
secretName: mutual-tls-certs
defaultMode: 0400

Once the files are available in your container or filesystem, you can configure an HTTPS agent:

const https = require('https');
const fs = require('fs');

const httpsAgent = new https.Agent({
  key: fs.readFileSync('/certs/client.key'),
  cert: fs.readFileSync('/certs/client.crt'),
  ca: fs.readFileSync('/certs/ca.pem'),
  rejectUnauthorized: true,
});

Using axios:

const axios = require('axios');

axios.get('https://secure-api.example.com', {
  httpsAgent,
}).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

At this point, your Node.js app is successfully authenticating itself using mutual TLS.


Summary

  • Java teams usually provide certificates as .jks
  • Node.js requires .key, .crt, and .pem
  • Convert JKS → PKCS12 → individual files
  • Store certs securely using Kubernetes/OpenShift secrets
  • Use https.Agent to enable mTLS in Node.js

This approach works reliably across enterprise APIs and hybrid Java/Node.js environments.


In the next post, we’ll cover how to enable mutual TLS on a Node.js server and how clients authenticate against it.

❤️ Support This Blog


If this post helped you, you can support my writing with a small donation. Thank you for reading.


Comments

Popular posts from this blog

fixed: embedded-redis: Unable to run on macOS Sonoma

Copying MDC Context Map in Web Clients: A Comprehensive Guide

Reset user password for your own Ghost blog