Back to Guides
CertificatesSecurity

Self-Signed Certificates: Complete Guide

When to use them, how to create them, and how to add them to your system's trust store.

10 min read
Self-Signed Certificates Visualization

What is a Self-Signed Certificate?

A self-signed certificate is a certificate where the issuer and subject are the same entity. Instead of a trusted Certificate Authority (CA) vouching for your identity, you sign the certificate yourself.

Think of it like writing your own reference letter instead of getting one from your previous employer. The content might be accurate, but there's no third party confirming it.

Key Point: Self-signed certificates provide the same encryption strength as CA-signed certificates. The only difference is the trust model - who vouches for the certificate's authenticity.

Self-Signed vs CA-Signed Certificates

Trust Model Comparison

CA-Signed
YouCA
CA validates identity
Trusted automatically
Self-Signed
YouYou
No external validation
Manual trust required

The fundamental difference is in the chain of trust:

CA-Signed

  • • CA verifies your identity
  • • CA signs with their private key
  • • Browsers trust the CA
  • • Therefore, browsers trust you

Self-Signed

  • • You sign with your own key
  • • No external validation
  • • Browsers don't trust by default
  • • Must manually add to trust store

When to Use Self-Signed Certificates

Local Development

localhost, 127.0.0.1, dev servers

Internal Testing

QA environments, staging servers

Lab/Sandbox Networks

Isolated test networks

Learning & Experimentation

Understanding TLS/PKI

IoT on Private Networks

Devices never exposed to internet

Air-Gapped Systems

Networks with no internet access

Internal Tools

With manual trust distribution

When NOT to Use Self-Signed Certificates

Public Websites

Use Let's Encrypt - it's free!

Production APIs

Customers can't trust your cert

E-commerce / Payments

Payment processors require CA certs

Mobile Apps

Certificate pinning is a better option

Public Services

Users will see scary warnings

Creating Self-Signed Certificates

Quick One-Liner (No SANs)

Fastest way to generate a self-signed cert:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"

With SANs (Recommended)

Modern browsers require Subject Alternative Names:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes \
  -subj "/CN=myapp.local" \
  -addext "subjectAltName=DNS:myapp.local,DNS:localhost,IP:127.0.0.1"

Generate Key First (Two-Step)

For more control over key generation:

# Generate private key
openssl genrsa -out key.pem 2048

# Generate self-signed certificate
openssl req -new -x509 -key key.pem -out cert.pem -days 365 \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

ECDSA (Modern, Smaller Keys)

Elliptic curve - same security, smaller keys:

openssl ecparam -genkey -name prime256v1 -out key.pem
openssl req -new -x509 -key key.pem -out cert.pem -days 365 \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

Command Flags Explained

-x509Output self-signed cert (not CSR)
-newkeyGenerate new private key
-nodesNo password on private key
-daysCertificate validity period
-subjSubject DN (avoid prompts)
-addextAdd X.509 extensions (SANs)

Adding to Trust Stores

To avoid browser warnings, add your self-signed certificate to your system's trust store:

macOS

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain cert.pem

Or drag cert into Keychain Access → System → set to "Always Trust"

Windows

certutil -addstore -f "ROOT" cert.pem

Or: certmgr.msc → Trusted Root Certification Authorities → Import

Linux (Ubuntu/Debian)

sudo cp cert.pem /usr/local/share/ca-certificates/myapp.crt
sudo update-ca-certificates

Node.js

NODE_EXTRA_CA_CERTS=/path/to/cert.pem node app.js

Python requests

requests.get('https://localhost', verify='/path/to/cert.pem')

Security Warning

Only add certificates to your trust store that you created yourself or received from a trusted source. Adding a malicious certificate allows attackers to intercept your encrypted traffic.

Self-Signed vs Let's Encrypt

AspectSelf-SignedLet's Encrypt
CostFreeFree
Browser TrustManual setupAutomatic
Setup TimeInstantMinutes
Works on localhostYesNo
Works offlineYesNo
RenewalManualAuto (90 days)
Public websitesNeverYes
Domain requiredNoYes

Bottom Line: Use Let's Encrypt for anything public-facing. Use self-signed only for local development and internal/isolated environments.

Understanding Browser Warnings

When you visit a site with a self-signed certificate, you'll see warnings like:

Your connection is not private

NET::ERR_CERT_AUTHORITY_INVALID

This is Expected!

The browser is correctly warning you that no trusted CA vouched for this certificate. For your own development servers, you can safely proceed or add the cert to your trust store.

Related Resources

Frequently Asked Questions

Is self-signed encryption less secure?

No. The encryption strength is identical to CA-signed certificates. The difference is only in who vouches for the certificate's authenticity, not the encryption itself.

Can I use self-signed for production?

Only for internal tools where you can distribute the certificate to all users manually. Never use self-signed for public-facing services - users will see scary warnings and many browsers won't even allow bypass.

Why does Chrome reject my localhost cert?

Modern Chrome requires Subject Alternative Names (SANs). Use the -addext "subjectAltName=..." flag when generating your cert.

How long should my self-signed cert be valid?

For development: 1-2 years is common. There's no external authority limiting validity, but longer durations mean more time to forget about expiration. Some browsers now warn about certs valid for more than 398 days.