How to Generate ECDSA Certificates with mkcert: A Complete Guide

Use the -ecdsa flag when running mkcert to generate ECDSA P-256 leaf certificates instead of the default RSA 2048-bit keys, while the root CA remains RSA 3072-bit.

mkcert is a zero-config tool for creating locally-trusted development certificates. While it defaults to RSA keys, you can easily generate ECDSA certificates with mkcert using a simple command-line flag. This guide explains the implementation details and usage based on the FiloSottile/mkcert source code.

Understanding mkcert's ECDSA Implementation

How the -ecdsa Flag Works in main.go

The command-line interface for mkcert defines the -ecdsa option in main.go at lines 57-60. When you include this flag, the boolean field ecdsa on the mkcert struct is set to true. This value persists through the certificate generation workflow and determines which cryptographic algorithm the tool uses for the leaf certificate.

Key Generation Logic in cert.go

The actual algorithm selection happens in cert.go within the generateKey function at lines 66-70. The code checks the m.ecdsa boolean:

  • If false (default): Generates an RSA 2048-bit key using rsa.GenerateKey
  • If true: Generates an ECDSA P-256 key using ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

The returned *ecdsa.PrivateKey implements the crypto.Signer interface, allowing the rest of the certificate creation pipeline to remain algorithm-agnostic. The X.509 template construction, SAN handling, and PEM encoding work identically for both RSA and ECDSA keys.

How to Generate ECDSA Certificates with mkcert

Basic ECDSA Certificate Generation

Before generating any certificates, you must install the local CA into your system trust store:

mkcert -install

Generate a simple ECDSA certificate for a single domain:

mkcert -ecdsa example.com

This produces two files:

  • example.com.pem — The ECDSA certificate signed by the local CA
  • example.com-key.pem — The ECDSA P-256 private key in PKCS#8 format

Advanced ECDSA Options

Generate certificates for multiple domains or IPs:

mkcert -ecdsa example.com www.example.com localhost 127.0.0.1 ::1

Enable client authentication (mTLS) with ECDSA keys:

mkcert -ecdsa -client example.com

Export the ECDSA certificate as a PKCS#12 bundle for legacy applications:

mkcert -ecdsa -pkcs12 example.com

This creates example.com.p12 containing both the certificate and private key.

Technical Details of ECDSA Certificate Generation

When you use the -ecdsa flag, mkcert maintains a hybrid cryptographic architecture:

  • Root CA: Always RSA 3072-bit, regardless of leaf certificate type. The root key is generated once during mkcert -install and stored in the CAROOT directory.
  • Leaf Certificate: ECDSA using the P-256 curve (secp256r1/prime256v1) when -ecdsa is specified.
  • Private Key Encoding: PKCS#8 format, which supports both RSA and ECDSA keys uniformly. This ensures compatibility with modern TLS libraries and tools.
  • Certificate Template: The X.509 template construction in makeCert remains identical whether using RSA or ECDSA, as the crypto.Signer interface abstracts the signing operation.

Summary

  • Use mkcert -ecdsa to generate ECDSA P-256 leaf certificates instead of default RSA 2048-bit keys.
  • The root CA always remains RSA 3072-bit, created during mkcert -install.
  • The -ecdsa flag is parsed in main.go and triggers ecdsa.GenerateKey(elliptic.P256(), rand.Reader) in cert.go.
  • ECDSA certificates support all standard mkcert features: multiple SANs, client auth (-client), and PKCS#12 export (-pkcs12).
  • Private keys are encoded in PKCS#8 format, ensuring broad compatibility with modern TLS implementations.

Frequently Asked Questions

Does mkcert support ECDSA P-384 or P-521 curves?

No. According to the source code in cert.go, mkcert hardcodes the P-256 curve using elliptic.P256() when the -ecdsa flag is set. There is no command-line option to select alternative curves like P-384 or P-521. If you require different curve parameters, you would need to modify the source code and rebuild mkcert.

Why does the root CA remain RSA when using -ecdsa?

The root CA is generated once during mkcert -install and always uses RSA 3072-bit keys, as implemented in the newCA function. This design decision ensures maximum compatibility with legacy systems and trust stores that may have limited ECDSA support. Only the leaf certificates (the ones you generate for your local domains) use ECDSA when you specify the -ecdsa flag, creating a hybrid setup that balances modern cryptography with broad trust anchor compatibility.

Can I use ECDSA certificates with mkcert's -pkcs12 option?

Yes. The -pkcs12 flag works identically with ECDSA certificates. When you run mkcert -ecdsa -pkcs12 example.com, the tool generates an ECDSA P-256 key pair, creates the certificate, and packages both into a PKCS#12 bundle (.p12 file). The private key is encoded in PKCS#8 format within the bundle, which supports both RSA and ECDSA algorithms, ensuring compatibility with applications that require PKCS#12 imports.

Are ECDSA certificates generated by mkcert compatible with all browsers?

ECDSA certificates generated by mkcert are compatible with all modern browsers, including Chrome, Firefox, Safari, and Edge. However, very old operating systems or legacy applications that lack ECDSA support may fail to validate these certificates. Since mkcert's root CA is RSA-based, the trust anchor remains widely compatible, but the leaf certificate's ECDSA signature requires TLS libraries that support ECDSA cipher suites. For maximum compatibility in legacy environments, omit the -ecdsa flag to use RSA 2048-bit certificates.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →