| Tested on | Ubuntu 26.04 LTS (Resolute Raccoon) |
|---|---|
| Package | openssl 3.5.5 |
| Applies to | Linux systems with OpenSSL 3.x |
| Privilege | Normal user in a private working directory |
| Scope | Generate a root CA private key (with or without a passphrase), create a self-signed root certificate with basicConstraints and keyCertSign, verify it with OpenSSL, and protect the root key. Does not cover openssl ca issuance databases, leaf signing, or installing the root into OS trust stores. |
| Related guides | Generate a CSR with OpenSSL OpenSSL tutorial |
A root CA is your own trust anchor: a private signing key plus a self-signed X.509 certificate that other systems can choose to trust. Common uses include:
- Internal HTTPS and mTLS between services you operate
- VPNs and homelab PKI when you control every client
- Lab and staging environments before you buy public certificates
It is not a substitute for a publicly trusted CA on the open internet.
This walkthrough covers creating and verifying that root certificate with the OpenSSL CLI. It does not cover:
- Operating an issuing CA with
index.txt, serial files, andopenssl ca(a separate workflow) - Installing the root into Debian or RHEL trust stores (see the trust-store guide when you distribute
root-ca.crt)
Quick answer
A root CA pairs a private key with a self-signed certificate whose extensions mark it as a certification authority:
basicConstraints = critical, CA:truekeyUsagethat includeskeyCertSign(and usuallycRLSign)
For a private root on Linux under ~/private-root-ca, work through these steps in order (commands and sample output for each step follow in the sections below):
- Step-1 — Create
~/private-root-ca/privateand restrict directory permissions. - Step-2 — Generate a 4096-bit RSA root key with
openssl genpkey(passphrase-protected with-aes-256-cbc, or unencrypted for an isolated lab), then runchmod 400on the key file. - Step-3 — Issue the self-signed root certificate with
openssl req -new -x509and-addextfor CA extensions. - Step-4 — Verify subject and issuer,
CA:TRUEand key usage,openssl verify, and the SHA-256 fingerprint. - Step-5 — Protect
root-ca.keyand distribute onlyroot-ca.crt. - Step-6 — Sign an intermediate CA for day-to-day issuance instead of signing server certificates directly from the root.
openssl ca as a sample minimal CA application: no database locking and not production-grade as shipped. See openssl ca vs openssl x509 when you need signing with a CA database versus one-off x509 operations. A private CA can still be appropriate for internal infrastructure when keys, storage, and issuance are managed deliberately, not because the toolkit alone equals a managed PKI product.
What is a root CA?
In PKI and certificate authority terms, a root certificate authority sits at the top of a chain:
- Its certificate is self-signed (
subjectequalsissuer). - Clients that trust the root accept descendant certificates signed under that hierarchy.
A self-signed server certificate is also self-signed, but it identifies one host or service, not a signing authority. For a single-host TLS file without CA extensions, see generate a self-signed certificate with OpenSSL. The root-versus-server distinction is in X.509 extensions, not in the phrase “self-signed.”
Root CA vs self-signed server certificate
| Root CA | Self-signed server / leaf cert | |
|---|---|---|
| Purpose | Sign subordinate CA or end-entity certificates | Identify one TLS endpoint |
Typical basicConstraints |
CA:TRUE |
absent or CA:FALSE |
Typical keyUsage |
keyCertSign, cRLSign |
digitalSignature, keyEncipherment (etc.) |
| Private key exposure | Must stay highly protected | Protect on the server, narrower blast radius |
Root CA vs intermediate CA
A common PKI design is to:
- Keep the root offline and use an intermediate CA online for day-to-day signing
- Limit blast radius if the issuing key is compromised
This page stops at the root; the next guide builds root, intermediate, and leaf certificates.
┌───────────────────────────────┐
│ Root CA │
│ (offline trust anchor) │
│ root-ca.crt / root-ca.key │
└───────────────┬───────────────┘
│ signs
▼
┌───────────────────────────────┐
│ Intermediate CA │
│ (issuing CA) │
└───────────────┬───────────────┘
│
┌──────┴──────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Server cert │ │ Client cert │
└───────────────┘ └───────────────┘
Distribute: root-ca.crt
Protect: root-ca.keyPrerequisites
You need the openssl binary. On Ubuntu and Debian, install OpenSSL with apt if it is missing; most server images already include it.
Confirm the major version—this walkthrough uses OpenSSL 3.x syntax (genpkey, -addext):
openssl versionOpenSSL 3.5.5 27 Jan 2026 (Library: OpenSSL 3.5.5 27 Jan 2026)Before you generate keys:
- Work in a directory only you can read (
chmod 700onprivate/). - You do not need root unless you later install
root-ca.crtinto a system-wide trust store.
Step 1: Create a working directory for the root CA
Generate keys and certificates in a dedicated tree so permissions stay obvious. Create the layout under your home directory:
mkdir -p ~/private-root-ca/privateRestrict the directory so only your user can list or create files there:
chmod 700 ~/private-root-ca/privateThe private key is written directly into the restricted private/ directory.
Step 2: Generate the root CA private key
Use openssl genpkey for OpenSSL 3.x. Older tutorials often use openssl genrsa; genpkey is the general interface for RSA and ECC—see generate an ECC certificate with OpenSSL when you prefer an elliptic-curve root.
With a passphrase (recommended)
Passphrase encryption protects the key file if it is copied off disk. OpenSSL prompts when you create the key and again when you use it in req:
openssl genpkey -algorithm RSA -aes-256-cbc -pkeyopt rsa_keygen_bits:4096 -out ~/private-root-ca/private/root-ca.keyChoose a passphrase you can store securely. Without it, the encrypted root key is unusable. The main options on this command:
-algorithm RSA— RSA key (widely compatible for a root)-aes-256-cbc— encrypt the key file with AES-256-CBC; OpenSSL prompts for the passphrase-pkeyopt rsa_keygen_bits:4096— 4096-bit modulus-out …/root-ca.key— write the key directly into your restrictedprivate/directory
Without a passphrase
Skip -aes-256-cbc when you need a throwaway lab root or scripted signing where another layer (offline storage, HSM, or short-lived VM) already controls access. The key file is readable by anyone who can read the file and your chmod settings:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out ~/private-root-ca/private/root-ca.keygenpkey exits silently on success. Use the same -algorithm RSA, -pkeyopt rsa_keygen_bits:4096, and -out paths as above, but omit -aes-256-cbc so the key is stored in plain PEM. Do not use an unencrypted root key on shared hosts or long-lived production PKI unless policy explicitly allows it.
Restrict the private key file
Whether the key is encrypted or not, remove group and other access:
chmod 400 ~/private-root-ca/private/root-ca.keyPassphrase or plain key?
If someone copies the root private key, they can issue certificates that every trust store honoring your root will accept. Mitigations include:
- AES-256-CBC encryption at key generation (
-aes-256-cbc) when humans or break-glass processes unlock the key chmod 400so other local users cannot read the file- Offline storage or an HSM when the root is not signing
- Omitting the passphrase only when the environment is isolated and the risk is understood
Use the root key sparingly, typically to sign an intermediate, not end-entity certificates.
Step 3: Create the self-signed root CA certificate
Issue the root certificate with openssl req -new -x509, SHA-256, and explicit extensions via -addext so CA properties are visible in the command.
openssl req -new -x509 \
-key ~/private-root-ca/private/root-ca.key \
-sha256 \
-days 3650 \
-out ~/private-root-ca/root-ca.crt \
-subj "/C=IN/O=Example/CN=Example Root CA" \
-addext "basicConstraints=critical,CA:true,pathlen:1" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash" \
-addext "authorityKeyIdentifier=keyid:always,issuer"OpenSSL prompts for the key passphrase only when root-ca.key is encrypted. The flags and values in this command mean:
req— certificate request tool; combined with-x509it builds and signs the certificate in one step.-new— create a new request or certificate (do not reuse an old CSR on disk).-x509— write a self-signed X.509 certificate instead of outputting a CSR for another CA to sign.-key ~/private-root-ca/private/root-ca.key— private key that signs the certificate (must match the public key embedded in the cert).-sha256— sign the certificate with SHA-256 (use a modern digest, not SHA-1).-days 3650— validity period of 3,650 days from issuance (~10 years). Pick a shorter or longer value to match your PKI policy and intermediate or leaf lifetimes.-out ~/private-root-ca/root-ca.crt— PEM file for the root certificate (safe to copy to clients; not the private key).-subj "/C=IN/O=Example/CN=Example Root CA"— distinguished name baked into subject and issuer (self-signed, so they match):C=IN— country codeO=Example— organizationCN=Example Root CA— common name shown as the CA title
-addext "basicConstraints=critical,CA:true,pathlen:1"— marks the cert as a CA;criticalmeans reject if unsupported;pathlen:1allows one subordinate CA level below this root (root → intermediate → leaf).-addext "keyUsage=critical,keyCertSign,cRLSign"— CA may sign other certificates and CRLs; required profile whenkeyUsageis present on a CA cert.-addext "subjectKeyIdentifier=hash"— SKI derived from the public key (helps chain building).-addext "authorityKeyIdentifier=keyid:always,issuer"— AKI points at this cert’s key and issuer DN (on a self-signed root, SKI and AKI refer to the same anchor).
After the root certificate expires:
- You do not extend the old file in place; you issue a new root certificate.
- You may reuse the existing private key where policy allows, or generate a new root key during rollover.
- See renew an expired root CA certificate for the OpenSSL steps.
For a larger CA workflow, move these extensions into openssl.cnf from the certificate chain guide instead of repeating -addext on every command.
Required CA extensions
A proper root CA certificate in this guide includes:
basicConstraints = critical, CA:TRUE(andpathlenwhen you want a depth limit)keyUsage = critical, keyCertSign, cRLSign
How those fields interact:
basicConstraintswithCA:TRUEis what marks the certificate as a CA (not merely self-signed).keyUsageis not required on every X.509 CA certificate the wayCA:TRUEis.- When
keyUsageis present, it must includekeyCertSignfor a signing CA. - Critical
keyUsagewithkeyCertSignandcRLSignfits a root that signs intermediates and may publish CRLs.
A self-signed certificate without CA:TRUE is not a root CA, even when subject and issuer match. For more extension patterns, see add x509 extensions to a certificate.
Choosing a pathlen value
pathlen is the maximum number of non-self-issued CA certificates that may appear below this CA in a valid chain. It is a deliberate design choice, not a limit on how many intermediate certificates you may ever issue over time.
pathlen:1— at most one additional CA level below the root, which fits root → intermediate → leaf.pathlen:0— this CA may issue end-entity certificates, but no subordinate CA certificate may appear beneath it.- Omit
pathlen— no depth constraint in the extension (more flexible if you may add CA levels later).
If you intend a single CA level between the root and leaf certificates, pathlen:1 is appropriate. Many examples omit pathlen on roots that might grow a deeper hierarchy later.
Step 4: Verify the root CA certificate
Work through these checks in order:
- Subject and issuer point at the same DN (self-signed root).
basicConstraintsandkeyUsageshowCA:TRUEand certificate signing.openssl verifyreturnsOKwhen the root file is its own trust anchor.- SHA-256 fingerprint is recorded before you distribute
root-ca.crt.
Check subject and issuer
A root CA should list the same distinguished name for subject and issuer:
openssl x509 -in ~/private-root-ca/root-ca.crt -noout -subject -issuer -datessubject=C=IN, O=Example, CN=Example Root CA
issuer=C=IN, O=Example, CN=Example Root CA
notBefore=Oct 17 13:03:14 2026 GMT
notAfter=Oct 14 13:03:14 2036 GMTMatching subject and issuer confirms the cert is self-signed. notBefore and notAfter bound the validity window.
Verify CA:TRUE and key usage
Scan the extensions instead of dumping the entire certificate:
openssl x509 -in ~/private-root-ca/root-ca.crt -noout -text | grep -A2 'Basic Constraints\|Key Usage' X509v3 Basic Constraints: critical
CA:TRUE, pathlen:1
X509v3 Key Usage: critical
Certificate Sign, CRL SignIn the extension output, expect:
CA:TRUE(andpathlen:1if you used that-addextvalue)Certificate Signunder Key UsageCRL Signwhen you includedcRLSign
Confirm the self-signed chain with openssl verify
Pass the same PEM file as both the trust anchor (-CAfile) and the certificate under test. When validation succeeds:
- OpenSSL prints
OKand the full path toroot-ca.crt. - That confirms signature and basic chain handling for this single-file check.
- It does not replace the subject, extension, and key-usage checks above.
openssl verify -CAfile ~/private-root-ca/root-ca.crt ~/private-root-ca/root-ca.crt/home/user/private-root-ca/root-ca.crt: OKRecord the SHA-256 fingerprint
Before you distribute root-ca.crt, record its fingerprint so clients can confirm they received the expected trust anchor:
openssl x509 -in ~/private-root-ca/root-ca.crt -noout -fingerprint -sha256sha256 Fingerprint=19:94:F3:C4:A4:06:04:88:1E:78:9A:D8:BB:DD:3C:37:2C:FA:1F:CB:B1:8F:45:BB:E1:C3:B6:19:68:E2:BF:17Share the fingerprint through a trusted channel, for example:
- Out-of-band message to the team importing the root
- Configuration management or secrets store metadata
- An internal runbook entry paired with the PEM file
Your fingerprint will differ because the key material is unique.
Step 5: Protect the root CA private key
Treat root-ca.key as the highest-value secret in your PKI:
- Do not copy it onto application servers or into container images.
- Do not commit it to git or paste it into tickets.
- Distribute only
root-ca.crtto clients that must trust your hierarchy. - Keep the root key offline when practical; sign intermediates in a controlled session.
If you must back up the key:
- Encrypt the backup media or archive
- Store it separately from
root-ca.crt - Use the same caution as for the live
root-ca.keyfile
Step 6: What to do next
Create an intermediate CA and certificate chain
A typical hierarchy:
- Root CA signs one intermediate CA (short, controlled root signing sessions).
- The intermediate signs server and client leaf certificates day to day.
- The root key stays offline; issuance happens on the intermediate.
Follow OpenSSL create certificate chain: root, intermediate and leaf for openssl ca layout, index.txt, CSRs, and fullchain.pem.
Add the root CA to the Linux trust store
Creating root-ca.crt does not automatically trust the CA in:
- Linux distribution CA bundles
- Desktop browsers
- Java
cacertsor application-specific trust stores
Import the certificate only with install and trust a CA certificate on Linux. Never install the private key into a trust store.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Certificate is self-signed but tools reject it as a CA | Missing or wrong basicConstraints / keyUsage |
Reissue with -addext "basicConstraints=critical,CA:true" and keyCertSign |
openssl verify fails on the root file |
File is not a valid X.509 cert or wrong path | Regenerate; confirm PEM headers with openssl x509 -in root-ca.crt -noout |
Cannot use encrypted root-ca.key |
Wrong passphrase or corrupt key | Restore from backup; there is no recovery without the passphrase |
| Clients trust nothing after import | Only leaf or intermediate installed, or wrong store | Install root .crt per distro trust-store steps |
Summary
You can create a private root CA on Linux with OpenSSL 3.x by generating a 4096-bit RSA root key (passphrase-protected or plain, depending on policy), issuing a self-signed root certificate with CA:TRUE and keyCertSign, and verifying subject/issuer match, extensions, openssl verify, and the SHA-256 fingerprint. That certificate is only the trust anchor: keep root-key use rare, sign an intermediate for routine issuance, and distribute only the public root certificate to clients.
openssl ca databases, CRL state, and leaf certificate signing belong in the dedicated certificate chain article, not in root creation. Public websites still need a publicly trusted CA; internal infrastructure can use your root when trust stores and private keys are managed deliberately.
References
- OpenSSL
genpkeydocumentation - OpenSSL
reqdocumentation - OpenSSL certificate verification (
openssl verify) - OpenSSL
cacommand (sample CA application)
Frequently Asked Questions
Why is a root CA self-signed?
No higher authority exists above a trust anchor, so the root certificate signs itself. Subordinate certificates are signed by the CA above them; the root is the stopping point for chain validation.
Can a root CA sign server certificates directly?
Technically yes, but it is poor practice. Keep the root offline and sign an intermediate CA for routine issuance so a compromised online key does not equal full PKI compromise.
How long should a root CA certificate be valid?
Lab guides often use 5–20 years. When you set -days, weigh:
- Shorter lifetimes — more frequent planned renewal work
- Longer lifetimes — less rotation overhead, but a lost key hurts longer
- Alignment with intermediate and leaf certificate lifetimes in the same PKI
Should I use RSA or ECC for a root CA?
RSA 4096-bit keys remain widely compatible. ECC roots provide strong security with smaller keys and certificates, but compatibility depends on the chosen curve and signature algorithms.

