Continuation sheet · reference notes
How it worksFour steps, all inside your browser.
- Drop everything your CA sent you.Certificate, intermediate, CA bundle or
.p7b, in any order and any mix of PEM and DER. Duplicates and stray files are fine. - The chain is rebuilt from the signatures.Each certificate is matched to its issuer by name and key identifier, then its signature is verified with the Web Crypto API. Filenames and order don't matter.
- Problems are spelled out.Missing intermediates come with the download address your CA publishes. Expired certificates, broken signatures and keys that don't match are flagged before you deploy.
- Download the file your server wants.
fullchain.pem,chain.pem,cert.pemor a combined certificate-and-key PEM, as clean 64-column PEM.
What goes in fullchain.pemCertificate order, leaf to root.
A TLS client trusts your site by walking a chain of signatures from your certificate up to a root CA it already holds. Your server must send every link except the root, in order:
Each block is a -----BEGIN CERTIFICATE----- section. Get the order wrong, or leave out an intermediate, and browsers may still connect (they cache intermediates) while curl, Java, Android apps and API clients fail with unable to get local issuer certificate.
Install the chain on your serverConfig snippets for common servers.
Nginx
Nginx takes the whole chain in ssl_certificate. Use fullchain.pem, never the leaf alone.
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
}
# test the config, then reload
sudo nginx -t && sudo systemctl reload nginx
Apache httpd
Apache 2.4.8 and later read the chain from SSLCertificateFile, so point it at fullchain.pem.
<VirtualHost *:443> ServerName example.com SSLEngine on SSLCertificateFile /etc/ssl/example.com/fullchain.pem SSLCertificateKeyFile /etc/ssl/example.com/privkey.pem </VirtualHost>
On Apache older than 2.4.8, use cert.pem for SSLCertificateFile and add SSLCertificateChainFile /etc/ssl/example.com/chain.pem.
sudo apachectl configtest && sudo systemctl reload apache2
HAProxy
HAProxy wants the chain and private key in one file. Add your key to the bag and choose Full chain + private key.
frontend https-in
bind :443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1
default_backend app
sudo chmod 600 /etc/haproxy/certs/example.com.pem haproxy -c -f /etc/haproxy/haproxy.cfg && sudo systemctl reload haproxy
Caddy
When you bring your own certificate, pass the full chain and key to the tls directive.
example.com {
tls /etc/ssl/example.com/fullchain.pem /etc/ssl/example.com/privkey.pem
reverse_proxy localhost:8080
}
Node.js
The cert option accepts the whole chain as one PEM string.
import https from 'node:https'; import { readFileSync } from 'node:fs'; https.createServer({ cert: readFileSync('/etc/ssl/example.com/fullchain.pem'), key: readFileSync('/etc/ssl/example.com/privkey.pem'), }, app).listen(443);
Kubernetes TLS secret
Ingress controllers serve whatever is in tls.crt, so it must hold the full chain.
kubectl create secret tls example-tls \ --cert=fullchain.pem \ --key=privkey.pem \ --namespace=web
Postfix
Postfix 3.4+ reads the key followed by the chain from smtpd_tls_chain_files.
# /etc/postfix/main.cf
smtpd_tls_chain_files =
/etc/ssl/mail.example.com/privkey.pem,
/etc/ssl/mail.example.com/fullchain.pem
sudo postfix check && sudo systemctl reload postfix
Check a chain with OpenSSLCommands to confirm what your server sends.
Verify the chain links up
openssl verify -untrusted chain.pem cert.pem
See the chain your server actually sends
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
List the certificates inside a bundle
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout
Convert other formats to PEM
# PKCS#7 (.p7b) to PEM openssl pkcs7 -print_certs -in bundle.p7b -out bundle.pem # DER (.cer / .der) to PEM openssl x509 -inform der -in cert.cer -out cert.pem # PKCS#12 (.pfx / .p12) to PEM certificates openssl pkcs12 -in site.pfx -nokeys -out certs.pem
Confirm a private key matches the certificate
openssl x509 -noout -pubkey -in cert.pem | openssl sha256
openssl pkey -pubout -in privkey.pem | openssl sha256
# the two hashes must be identical
How your files stay privateWhat this page can and can't do with your certificates and keys.
- Processing
- In this tab, with plain JavaScript and your browser's built-in Web Crypto API. Files are read with the File API and never leave memory.
- Network
- The page has no code that sends your data anywhere. Its Content-Security-Policy sets
connect-src 'none', which blocks every fetch, upload, WebSocket and beacon, and it lets only this page's own script run (matched by hash, with Trusted Types refusing injected HTML). A security policy can't stop a page from navigating away, so the real guarantee is that no other code can run here. The counters on the evidence form count third-party requests and blocked attempts live, and the Upload test tries a real outbound request when the page loads to prove the browser stops it. - Storage
- No cookies, no
localStorage, no IndexedDB, no service worker. Wipe everything zeroes the certificate and key bytes the page holds. A few copies it can't overwrite, such as text you pasted, are released when you close the tab. - Analytics
- None. No third-party scripts, fonts or images. Everything is served from this origin.
- Private keys
- Never shown in the preview and never copied to the clipboard, where clipboard managers could keep them. They go only into the file you download. The paste box turns off spellcheck and grammar extensions, which can send typed text to a server.
- Tamper guard
- While the page is open it watches itself. If anything other than its own code edits the page (developer tools, an injected script, an extension) or swaps out a browser function it relies on, every certificate and key is wiped from memory and the page reloads. If it happens again straight after, the generator locks and tells you why. If something between the site and you (a proxy, or an add-on feature of the host) slips in extra script, the browser won't run it, because only the script matching the hash in the security policy may run. No page can protect itself from whoever publishes the site, so the hosting and deploy accounts are locked down instead.
- Hosting
- Served as static files from Cloudflare. Like any website, the host sees that the page was requested. It never receives your files, because the page has no way to send them.
- Your side
- Browser extensions allowed to read every site can read this page too. For the strongest guarantee, open it in a private window with extensions off, or load it and then disconnect from the network.
The policy this page runs under
default-src 'none'; connect-src 'none'; form-action 'none'; …
QuestionsAbout certificate chains and this tool.
What is fullchain.pem?
fullchain.pem is your server (leaf) certificate followed by every intermediate CA certificate that links it to a trusted root, in PEM format. Web servers send the whole chain during the TLS handshake so clients can verify your certificate. The name comes from Certbot and Let's Encrypt, but certificates from any CA are combined the same way.
What order should the certificates be in?
Leaf first, then the intermediate that signed it, then the next intermediate, moving toward the root. Each certificate must be signed by the one after it. This generator checks those signatures and sorts the chain for you, whatever order your files arrive in.
Should I include the root certificate?
Usually not. Clients already hold trusted roots in their trust store, and TLS lets servers leave the self-signed root out. Including it only adds bytes to every handshake. Some appliances and older Java or embedded clients ask for it; for those, tick Include root CA.
What is the difference between fullchain.pem, chain.pem and cert.pem?
cert.pem is the leaf certificate alone, chain.pem holds only the intermediates, and fullchain.pem is cert.pem followed by chain.pem. Nginx, HAProxy and Apache 2.4.8 or later want fullchain.pem. Older Apache versions use cert.pem with SSLCertificateChainFile pointing at chain.pem.
Are my certificates or private key uploaded?
No. Files are read with the browser's File API and processed in this tab with JavaScript and the Web Crypto API. The page has no code that sends data anywhere. Its Content-Security-Policy blocks every fetch, upload and background connection, and lets no script run except the page's own. There are no cookies, analytics or storage. Close the tab and everything is gone.
Why would I add my private key?
Only if you need one combined PEM file, such as for HAProxy's crt option or some load balancers, which expect the certificate chain and private key together. The generator also confirms the key matches your certificate. The key is never shown in the preview and cannot be copied to the clipboard; it goes straight into the downloaded file.
My CA sent a .p7b or .pfx file. Can I use it?
PKCS#7 bundles (.p7b and .p7c) are supported: drop them in and their certificates are extracted. Password-protected .pfx and .p12 files are not supported; convert them first with openssl pkcs12 -in site.pfx -nokeys -out certs.pem.
What does "unable to get local issuer certificate" mean?
The client could not link your certificate to a trusted root, almost always because the server is not sending the intermediate certificate. Install fullchain.pem rather than the leaf certificate alone, then reload your server.
Which key and signature types are verified?
RSA with PKCS#1 v1.5 and PSS padding, ECDSA on P-256, P-384 and P-521, and Ed25519 where the browser supports it. Signatures are checked with the browser's built-in Web Crypto API.
Does it work offline?
Yes. Once the page has loaded it never needs the network. You can disconnect before adding your files.
Our customersWho uses our service.
We’ll never know that, since we don’t track anyone.