DomainLens

Guides

OpenSSL Commands: CSRs, Self-Signed Certificates and Format Conversion

Six commands cover almost every certificate task. The one worth memorising is s_client, because it shows what a server actually presents rather than what you believe you installed.

Check your site before you start fixing

Run a fresh DomainLens audit and use the report as your priority list.

Run a free SEO audit

Generating a key and a CSR

A certificate signing request bundles your public key with the identity you are claiming. The private key never leaves your server — that is the entire security model, so a provider offering to generate it for you is one to decline.

  • -nodes means the key is stored unencrypted, so the server can start without a passphrase prompt.
  • Browsers have ignored the Common Name for years — every hostname must appear in subjectAltName.
  • Guard the .key file: file permissions of 600 and never in version control.
Key and CSR in one step
# 2048-bit RSA key plus a CSR, prompting for details
openssl req -new -newkey rsa:2048 -nodes \
  -keyout example.com.key -out example.com.csr

# Non-interactive, with subject on the command line
openssl req -new -newkey rsa:2048 -nodes \
  -keyout example.com.key -out example.com.csr \
  -subj "/C=US/ST=State/L=City/O=Example Inc/CN=example.com"

# With subject alternative names — required by modern
# browsers, which ignore CN entirely
openssl req -new -newkey rsa:2048 -nodes \
  -keyout example.com.key -out example.com.csr \
  -subj "/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.com"

Self-signed certificates

Self-signed certificates are correct for local development and for origin servers behind a proxy that trusts them. They are never correct for a public site, because no browser trusts them and visitors get the same warning as an expired certificate.

A self-signed certificate with SANs
# Key and self-signed certificate, valid one year
openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
  -keyout local.key -out local.crt \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

# Without the SAN extension, Chrome rejects it outright
# regardless of what CN says.

Inspecting what is actually there

This is the genuinely useful category. Configuration files describe intent; these commands report reality.

The distinction matters more than it sounds. A certificate can be present on disk, referenced correctly in the configuration, and still not be what the server presents — because the process has not reloaded, because another virtual host matched first, or because a proxy in front terminates TLS with a certificate of its own. Only the handshake settles it.

When reading the output, three fields answer most questions: the subject and its alternative names tell you which hostnames are covered, the issuer tells you whether the certificate came from where you expect, and the validity dates tell you whether the problem is expiry or something else entirely.

  • -servername is required on shared hosts; without SNI you may be shown a different site's certificate.
  • The modulus comparison is the fastest way to diagnose a key/certificate mismatch.
  • -showcerts reveals a missing intermediate, which is why a certificate works in one client and fails in another.
Inspection commands
# What a live server presents — the important one
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -text

# Just the validity dates
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates

# Read a local certificate file
openssl x509 -in cert.pem -noout -subject -issuer -dates

# Read a CSR before submitting it
openssl req -in example.com.csr -noout -text

# Confirm a key matches its certificate — these must match
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa  -noout -modulus -in key.pem  | openssl md5

# Show the full chain the server sends
openssl s_client -connect example.com:443 -showcerts

Converting between formats

Certificate formats differ in encoding rather than content. PEM is base64 text with header lines, DER is the same structure in raw binary, and PKCS#12 is a container that bundles the certificate, its chain and the private key into one password-protected file. Converting between them changes the wrapper, never the certificate itself.

You need this most often when moving between server families. Linux servers want PEM files kept separate; Windows and IIS expect a single PKCS#12 bundle; some appliances and Java keystores want DER. A certificate that "does not work" on a new platform is frequently just the wrong container.

FormatExtensionUsed by
PEM.pem .crt .cernginx, Apache — base64 text
DER.der .cerJava, some appliances — binary
PKCS#12.pfx .p12Windows, IIS — bundles key and cert
PKCS#7.p7bChain only, no private key
The conversions you will need
# PEM -> PFX (for IIS)
openssl pkcs12 -export -out cert.pfx \
  -inkey key.pem -in cert.pem -certfile chain.pem

# PFX -> PEM (extract both parts)
openssl pkcs12 -in cert.pfx -out cert.pem -nokeys
openssl pkcs12 -in cert.pfx -out key.pem -nocerts -nodes

# DER -> PEM
openssl x509 -inform der -in cert.der -out cert.pem

How DomainLens contributes

The s_client commands above answer one question — what is this server presenting right now — and the SSL checker answers it without a terminal, reporting issuer, dates and protocol for any host. For issuing certificates automatically see certbot and Let's Encrypt .

What is a CSR?
A certificate signing request: your public key plus the identity you are claiming, signed by your private key. The authority validates it and returns a certificate. The private key never leaves your server.
Why does Chrome reject my self-signed certificate?
Usually because it has no subjectAltName. Modern browsers ignore the Common Name entirely and require every hostname in the SAN extension.
What is the difference between .pem and .crt?
Usually nothing — both typically hold base64 PEM data and the extension is convention. Check the contents rather than trusting the name.
How do I check whether a key matches a certificate?
Compare their moduli with openssl and hash each. Identical hashes mean they belong together; different ones explain why the server refuses to start.

Related resources