mkcert Default Key Generation Parameters: RSA 2048 vs 3072 Explained
mkcert generates RSA 2048-bit keys for leaf certificates by default, but uses RSA 3072-bit keys for the root CA, unless the -ecdsa flag is specified to use P-256 elliptic curve cryptography instead.
The mkcert tool simplifies local HTTPS development by automatically creating and trusting locally-signed certificates. Understanding its default key generation parameters helps developers assess security trade-offs and compliance requirements when deploying local development environments.
How mkcert Generates Keys by Default
When you run mkcert without the -ecdsa flag, it creates RSA keys through the generateKey function in cert.go. The bit length varies based on whether the key is intended for a leaf certificate or the root Certificate Authority (CA).
Leaf Certificates: RSA 2048
For standard domain certificates (leaf certificates), mkcert defaults to 2048-bit RSA keys. When you execute mkcert example.com, the tool calls makeCert(), which invokes generateKey(false):
// From makeCert() in cert.go (lines 55-57)
priv, err := m.generateKey(false)
Inside generateKey(), when rootCA is false, the function returns:
return rsa.GenerateKey(rand.Reader, 2048)
This 2048-bit default balances security with performance for temporary development certificates.
Root CA: RSA 3072
When installing a new local CA via mkcert -install, the tool generates a 3072-bit RSA key for the root certificate. The newCA() function calls generateKey(true):
// From newCA() in cert.go (lines 110-115)
priv, err := m.generateKey(true)
In generateKey(), the true parameter triggers the higher bit length:
return rsa.GenerateKey(rand.Reader, 3072)
The stronger 3072-bit key for the root CA provides enhanced security for the trust anchor, following CA/Browser Forum baseline requirements that recommend minimum 2048-bit keys but prefer 3072-bit or higher for root certificates.
The generateKey Function in cert.go
The conditional logic resides in cert.go at lines 66-74, where generateKey determines which cryptographic parameters to use based on the rootCA boolean and the global ECDSA flag:
func (m *mkcert) generateKey(rootCA bool) (crypto.PrivateKey, error) {
if m.ecdsa {
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}
if rootCA {
return rsa.GenerateKey(rand.Reader, 3072)
}
return rsa.GenerateKey(rand.Reader, 2048)
}
This implementation clearly shows the three code paths: ECDSA P-256 when the flag is set, RSA 3072 for root CA creation, and RSA 2048 for all other certificates.
ECDSA Alternative: P-256 Curve
When you specify the -ecdsa flag, mkcert bypasses RSA entirely and generates ECDSA keys using the P-256 elliptic curve (also known as secp256r1 or prime256v1). This path executes regardless of whether the key is for a root CA or leaf certificate:
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
P-256 provides equivalent security to RSA 3072 but with significantly smaller key sizes and faster operations. However, some legacy systems may not support ECDSA, which is why RSA 2048 remains the default for leaf certificates.
Summary
- Leaf certificates use RSA 2048-bit keys by default, generated via
generateKey(false)incert.go. - Root CA certificates use RSA 3072-bit keys, generated via
generateKey(true)when runningmkcert -install. - ECDSA P-256 keys are generated when the
-ecdsaflag is specified, bypassing RSA entirely. - The logic resides in the
generateKeyfunction at lines 66-74 ofcert.go, which checks therootCAboolean and global ECDSA configuration.
Frequently Asked Questions
Why does mkcert use RSA 3072 for the root CA but 2048 for leaf certificates?
The root CA serves as the trust anchor for all locally-generated certificates, requiring stronger cryptographic protection to prevent compromise of the entire PKI hierarchy. The 3072-bit key provides security margins appropriate for a long-lived root certificate, while 2048-bit keys offer sufficient security for temporary development certificates with better performance characteristics.
Can I change the default RSA key size in mkcert?
No, the RSA key sizes are hardcoded in the generateKey function in cert.go. To use different key lengths, you would need to modify the source code and recompile mkcert, changing the 3072 or 2048 parameters in the rsa.GenerateKey calls. There are no command-line flags to adjust RSA key sizes at runtime.
What happens when I use the -ecdsa flag?
When you specify -ecdsa, mkcert generates ECDSA keys using the P-256 elliptic curve instead of RSA keys. This applies to both root CA and leaf certificate generation. P-256 provides security comparable to RSA 3072 but with smaller key sizes and faster cryptographic operations. Note that some older systems or specific applications may not support ECDSA certificates.
Where is the key generation logic located in the mkcert source code?
The key generation logic resides in the generateKey method in cert.go at lines 66-74. This function checks whether the ecdsa field is set on the mkcert struct, then falls back to RSA generation with conditional logic based on the rootCA boolean parameter. The newCA() function (lines 110-115) and makeCert() function (lines 55-57) serve as the entry points that invoke generateKey with the appropriate boolean values.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →