How-to guide · Trust a CA
How to trust a private root CA on Windows
In one sentence
Your Windows computer, or a whole fleet, trusts your organisation's private root CA, and you know which apps still need their own setting.
- Task
- Trust a CA
- Platforms
- Windows
- Level
- Practitioner · 5 steps
On this page
Before you start
- The root certificate of your private CA as a file (
.ceror.crt, DER or PEM). Only the public certificate: never a.pfxand never a private key. - Its SHA-256 fingerprint, from a channel you trust (your PKI team’s HTTPS intranet page, a signed ticket), not from the email that carried the file.
- Administrator rights for the computer-wide store. Your own user store needs none.
- For many machines: rights to edit a Group Policy Object or an Intune configuration profile.
Why it matters: a root in the Windows trust store can vouch for any name, for every program that uses Windows certificate checking. Add only roots your organisation controls.
Steps
1. Check the file before you trust it
certutil -dump only reads the file. It accepts PEM and DER. This is the output for our throwaway test root on Windows 11, shortened:
certutil -dump corp-root.crt
X509 Certificate:
Version: 3
Serial Number: 15d0a60c3f02987ab1646cb51bba6b3d07450314
...
Issuer:
CN=Example Corp Root CA
O=Example Corp
C=BE
...
NotAfter: 2036-10-17 3:43 AM
Subject:
CN=Example Corp Root CA
...
Subject Type=CA
...
Root Certificate: Subject matches Issuer
Cert Hash(sha1): 3a5470d89c8577fedcb81710def42371214af708
Cert Hash(sha256): bc02a4f5dc68b3fdcdc478030e308cb59d6da0845aa0b4333660788e96c22e01
Three things to confirm:
Cert Hash(sha256)equals the fingerprint your PKI team published. OpenSSL prints the same value with colons:openssl x509 -in corp-root.crt -noout -fingerprint -sha256.Subject Type=CAandRoot Certificate: Subject matches Issuer. If the subject and issuer differ, you have an intermediate or a server certificate, not a root.NotAfteris years away.
You can also paste the PEM text into the decoder. It runs in your browser; never paste a private key into any website.
2. Choose the store
| Store (console name) | PowerShell path | Who trusts it |
|---|---|---|
| Trusted Root Certification Authorities, computer | Cert:\LocalMachine\Root |
Every user and every service. The normal choice. Needs administrator rights. |
| Trusted Root Certification Authorities, current user | Cert:\CurrentUser\Root |
Only you. Services running under other accounts do not see it. |
| Intermediate Certification Authorities | Cert:\LocalMachine\CA |
For intermediates only. Never put an intermediate in a Root store. |
The Personal store (My) holds certificates that have private keys, such as a server’s own certificate. It is not a trust store.
3. Import it on one computer
In PowerShell as administrator, with the Import-Certificate cmdlet:
Import-Certificate -FilePath .\corp-root.cer -CertStoreLocation Cert:\LocalMachine\Root
Or with certutil, in an administrator Command Prompt or PowerShell:
certutil -addstore -f Root corp-root.cer
For your own account only, use Cert:\CurrentUser\Root or certutil -user -addstore Root corp-root.cer. Windows then shows a Security Warning with the certificate’s SHA-1 thumbprint: compare it with Cert Hash(sha1) from step 1 before you click Yes.
Without the command line: run certlm.msc (computer) or certmgr.msc (current user), open Trusted Root Certification Authorities, right-click Certificates, choose All Tasks > Import and follow the wizard.
If a tool rejects a PEM file, convert it to DER first (how to convert between DER and PEM):
openssl x509 -in corp-root.crt -outform DER -out corp-root.cer
4. Or roll it out to many computers
Hand-imports drift. On a fleet, pick one central method:
- Group Policy (Microsoft’s procedure): edit a GPO linked to the right OU, open Computer Configuration\Policies\Windows Settings\Security Settings\Public Key Policies, right-click Trusted Root Certification Authorities and choose Import. Computers pick it up at the next policy refresh;
gpupdate /forcespeeds up one machine. - Intune (trusted certificate profiles): Devices > Manage devices > Configuration > Create, platform Windows 10 and later, Templates > Trusted certificate. Upload the DER
.cerfile and choose the destination store Computer certificate store - Root. Deploy intermediates in a separate profile to Computer certificate store - Intermediate. - Active Directory:
certutil -dspublish -f corp-root.cer RootCApublishes the root to the directory’s Trusted Root store, which domain members download. An enterprise AD CS root is published there when it is installed.
5. Point the apps that ignore the Windows store
Many tools use their own list of roots. Check each one your users run:
| Program | Uses the Windows store? | What to do |
|---|---|---|
| Edge, Chrome | Yes: Chrome reads roots added to the computer and user stores (Chrome Root Store FAQ) | Restart the browser |
| Firefox | Yes, by default since Firefox 120, through security.enterprise_roots.enabled (Mozilla) |
Restart Firefox |
.NET, PowerShell, curl.exe from Windows |
Yes | Nothing |
| Git for Windows | Only with the Schannel backend | git config --global http.sslBackend schannel |
| Node.js, npm | No | node --use-system-ca (Node.js 22.15 or later), or NODE_EXTRA_CA_CERTS: see Python, Node.js and npm |
| pip 24.2 and later | Yes, in addition to its own bundle | Nothing |
Python requests |
No, it uses certifi | See Python, Node.js and npm |
| Java | No, it uses cacerts |
See Java trust stores |
| WSL, Docker containers | No, they are Linux | See Linux |
Check it worked
List the root in the computer store. This view also includes roots that arrive through Group Policy or Active Directory:
Get-ChildItem Cert:\LocalMachine\Root | Where-Object Subject -like '*Example Corp Root CA*' | Format-List Subject, Thumbprint, NotAfter
Then ask Windows to verify the root file. Before the import, our test machine said:
certutil -verify corp-root.crt
ChainContext.dwErrorStatus = CERT_TRUST_IS_UNTRUSTED_ROOT (0x20)
...
A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
0x800b0109 (-2146762487 CERT_E_UNTRUSTEDROOT)
Verifies against UNTRUSTED root
After the import, CERT_E_UNTRUSTEDROOT disappears. Finally, open an internal site in Edge, or test from the command line with the curl.exe that ships with Windows:
curl.exe -sS -o NUL -w "%{http_code}`n" https://intranet.example.com/
A status code such as 200 means the TLS check passed.
If something goes wrong
- The browser still says
NET::ERR_CERT_AUTHORITY_INVALIDorSEC_ERROR_UNKNOWN_ISSUER. The root is in the wrong store (Personal or Intermediate), the browser was not restarted, or the server’s chain ends at a different root. Compare the issuer in the browser’s certificate viewer with your file. - A service or script still fails with
Could not establish trust relationshiporThe remote certificate is invalid. It probably runs under another account, which does not see your current-user store: import into the computer store. - Windows works, but Node.js, Java, Python or Git fail. They use their own store: see step 5 and
SELF_SIGNED_CERT_IN_CHAIN,PKIX path building failedorschannel: SEC_E_UNTRUSTED_ROOT. - Windows works, but other clients fail with “unable to get local issuer certificate”. Windows can download a missing intermediate; most other clients cannot. Fix the server: build the full chain file and see verify error 21.
curl.exereportsCRYPT_E_NO_REVOCATION_CHECKorCRYPT_E_REVOCATION_OFFLINE(with--cacert:schannel: the revocation status is unknown).curl.exeasks Windows to check revocation, and your CA’s certificates point to a CRL that clients cannot reach, or to none. Publish the CRL where clients can fetch it (revocation). Turning the check off hides the problem.- The name does not match. Trusting the root does not fix
NET::ERR_CERT_COMMON_NAME_INVALID: the server certificate needs the name in its Subject Alternative Name. - Group Policy has not arrived. Run
gpupdate /force, thengpresult /rto see which GPOs applied.
Why this works
When a program asks Windows to check a server certificate, Windows builds a certificate chain up through the intermediates and accepts it only if it ends at a certificate in a Trusted Root store. The computer store applies to every account on the machine. Being self-signed does not make your root trustworthy; being in the store does (Who do we trust?). How the chain is built and checked is in Certificate chains and path validation, and how to design a private CA that is safe to trust is in A CA of your own.
Go deeper
- Import-Certificate: the PowerShell cmdlet and its store paths.
- certutil:
-addstore,-delstore,-verify,-dspublishand every option. - Distribute certificates with Group Policy: Microsoft’s step-by-step procedure.
- Intune trusted certificate profiles: fleet rollout, including the destination stores.
- Chrome Root Store FAQ: which Windows stores Chrome reads for local trust.
- Node.js
--use-system-ca: which Windows stores Node.js reads.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.