Self-signed vs CA-signed certificates

A self-signed certificate is its own issuer — nobody vouches for it, so every client must be configured to trust it individually. A CA-signed certificate is issued by an authority the client already trusts, so it is accepted with no configuration at all. The encryption is identical in both cases; the difference is purely about identity. Self-signed certificates are fine for local development and a poor fit for anything with users, because the usual workaround for the trust warning is to disable verification, which removes the protection TLS exists to provide.

Updated August 19, 2026 Verified against OpenSSL 3.5.7

The only difference #

Self-signed — subject and issuer are the same
openssl x509 -in self-signed.crt -noout -subject -issuer
Expected output
subject=CN = localhost
issuer=CN = localhost
CA-signed — the issuer is somebody else
openssl x509 -in ca-signed.crt -noout -subject -issuer
Expected output
subject=CN = example.com
issuer=C = US, O = Example CA, CN = Example Intermediate CA

That is the whole distinction. Everything else follows from it.

What is and is not different #

Self-signed CA-signed
Encryption strength Identical Identical
TLS protocol version Identical Identical
Cipher suites Identical Identical
Trusted by default No Yes
Identity verified by a third party No Yes
Revocable No Yes, via CRL or OCSP
Cost None None, with a free CA
Client configuration needed Per certificate, per machine None

Why the identity part matters #

Encryption without authentication protects you from a passive eavesdropper and not from an active one. An attacker who can intercept the connection presents their own self-signed certificate, and the client has no basis to tell it apart from yours — both are equally unvouched-for.

That is also why the usual workaround is so damaging. When a self-signed certificate produces a warning, the fix people reach for is curl -k, verify=False or NODE_TLS_REJECT_UNAUTHORIZED=0 — and those disable verification for every connection that code makes, not just the one that prompted it.

When self-signed is the right choice #

  • Local development. localhost with a certificate you generated is fine.
  • Throwaway test environments that no real data passes through.
  • A root CA certificate. Every root is self-signed by definition — that is what makes it a root.

When it is not #

  • Anything with real users, who will be taught to click through security warnings.
  • Anything a mobile app connects to, where certificate handling is stricter and the workarounds are worse.
  • Anything that needs revocation. A self-signed certificate cannot be revoked; if the key leaks your only options are to wait for expiry or manually remove it from every trust store it reached.

The middle path: a private CA #

For internal services, a private CA gives you the operational properties of a real CA without paying anyone. Trust the root once per machine, then issue as many certificates as you like:

Self-signed Private CA Public CA
Trust-store operations One per certificate One per machine, ever None
Works for external users No No Yes
Revocation No Yes Yes
Setup effort Lowest Moderate, once Low with ACME

See create a root CA and sign a CSR with it.

Generating a self-signed certificate correctly #

If you do want one, the SAN extension is not optional — without it browsers reject the certificate even after you have trusted it:

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

Full detail at generate a self-signed certificate.

Frequently asked questions

Is a self-signed certificate less secure?
The encryption is exactly the same — same algorithms, same key sizes, same TLS. What is missing is identity assurance. Nothing independent attests that the certificate belongs to who it claims to, so a client cannot distinguish the real server from an interceptor presenting a different self-signed certificate.
Can I use a self-signed certificate in production?
Only where you control every client and can install the certificate in each one — internal service-to-service traffic, for example. For anything with users, the browser warning trains people to click through security warnings, and the usual developer workaround is to disable verification entirely.
How do I tell if a certificate is self-signed?
Compare subject and issuer. If they are identical, it is self-signed. openssl x509 -in certificate.crt -noout -subject -issuer answers it in one command.
What about Let's Encrypt?
Let's Encrypt is a real, publicly trusted CA and its certificates are CA-signed. They are free and automatable, which removes most of the reasons people historically reached for self-signed certificates on public services. See how to get a free TLS certificate.

References