Mutual TLS (mTLS) certificate generator

A complete mutual TLS bundle: one CA, one server certificate, and up to 10 client certificates — each also exported as a password-protected PKCS#12 file ready for browsers and operating systems. Everything runs in your browser; nothing is uploaded.

Mutual TLS bundle Up to 10 client certificates PKCS#12 export · RSA 2048 · SAN

One CA, one server certificate and up to 10 client certificates, each with a downloadable .p12 bundle for browsers and operating systems.

Use ASCII characters for the CA name.


Separate entries with commas or spaces. The Common Name is always added automatically.


Clients are named client-1, client-2, … Each gets a certificate, a private key and a .p12 bundle containing the client certificate, its key and the CA certificate. Use letters, digits, dots, hyphens and underscores only.

ca.crt Root CA certificate — install on the server and on clients
ca.key Root CA private key — store offline, never on the web server
server.key Server private key (PEM) — never share it
server.crt Server certificate (PEM), signed by the CA above

Client certificates

How to enable mutual TLS in Nginx

1. Install the server side

sudo mkdir -p /etc/nginx/ssl
sudo cp server.crt ca.crt /etc/nginx/ssl/
sudo cp server.key /etc/nginx/ssl/server.key
sudo chmod 600 /etc/nginx/ssl/server.key

2. Require a client certificate

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate         /etc/nginx/ssl/server.crt;
    ssl_certificate_key     /etc/nginx/ssl/server.key;

    # CA that signed the client certificates
    ssl_client_certificate  /etc/nginx/ssl/ca.crt;
    ssl_verify_client       on;
    ssl_verify_depth        2;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:SSL:10m;

    location / {
        proxy_set_header X-Client-DN $ssl_client_s_dn;
        proxy_set_header X-Client-Verify $ssl_client_verify;
        proxy_pass http://127.0.0.1:8080;
    }
}

Use ssl_verify_client optional instead of on if you want to accept both regular visitors and authenticated clients, then check $ssl_client_verify in your application.

3. Test and reload

sudo nginx -t
sudo systemctl reload nginx

4. Connect as a client

# PEM certificate + key
curl --cacert ca.crt --cert client-1.crt --key client-1.key https://example.com/

# PKCS#12 bundle
curl --cacert ca.crt --cert-type P12 --cert client-1.p12:changeit https://example.com/

5. Install a client bundle on your computer

Double-clicking a .p12 file imports the client certificate and its key together; enter the export password when prompted.

  1. Double-click client-1.p12 to start the Certificate Import Wizard.
  2. Choose Current User (or Local Machine for services), then Next.
  3. Enter the export password and tick Mark this key as exportable if you may move it later.
  4. Select Automatically select the certificate store → Next → Finish.
  5. Chrome and Edge will now offer this certificate when a site requests one. Verify under Settings → Privacy and security → Security → Manage device certificates.

Command line equivalent:

certutil -importpfx -user -p changeit client-1.p12
certutil -store -user My

6. Trust the CA so clients accept the server

Clients still need ca.crt in their trust store, otherwise they will reject the server certificate.

  1. Double-click ca.crt, then choose Install Certificate….
  2. Select Local Machine → Next (confirm the UAC prompt).
  3. Choose Place all certificates in the following storeBrowse…
  4. Pick Trusted Root Certification Authorities → Next → Finish.
certutil -addstore -f "ROOT" ca.crt
certutil -store ROOT

Also try: Self-Signed Certificate Generator · Private CA Certificate Generator · CSR Generator · Certificate Decoder