# Extract certificates from a PFX / P12

To extract only the server certificate from a PFX, run `openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.crt`. For the CA chain, swap `-clcerts` for `-cacerts`. The `-nokeys` flag suppresses the private key, so neither command writes a key to disk — useful when you only need the certificate and would rather not have an unencrypted key lying around. Add `-legacy` if OpenSSL 3 refuses the archive.

Source: https://certguru.io/openssl/extract-cert-from-pkcs12/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

## The server certificate

```bash
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.crt
```

## The CA chain

```bash
openssl pkcs12 -in certificate.pfx -cacerts -nokeys -out chain.crt
```

| Placeholder | What to put there |
| --- | --- |
| `-clcerts` | End-entity certificate only — the one for your hostname. |
| `-cacerts` | CA certificates only — the intermediates. |
| `-nokeys` | Do not write the private key. The key stays in the archive. |

> **Prefer -nokeys when you can**
>
> Extracting a certificate needs no key on disk. Leaving `-nokeys` off writes an unencrypted private
>   key you then have to remember to protect and delete. If you do need it, see
>   [extracting the private key](/openssl/extract-key-from-pkcs12/).

## Look before you extract

```bash
openssl pkcs12 -in certificate.pfx -info -noout
```

Expected output:

```
MAC: sha256, Iteration 2048
Certificate bag
Certificate bag
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC
```

Two certificate bags means a leaf plus one intermediate, so `-cacerts` will produce one certificate.
A single bag means there is no chain in the archive and `-cacerts` writes an empty file — which is
the usual explanation for "the command produced nothing".

## Can you read the certificates without the password?

Almost always no, and the reason is worth knowing because it is widely stated the other way round.

A PKCS#12 archive protects the private key with its own encryption, and it *also* wraps the
certificate bags in an encrypted PKCS#7 structure by default. So the password is needed for both:

*A default archive encrypts its certificates too*

```bash
openssl pkcs12 -in certificate.pfx -info -noout -passin pass:testpass 2>&1 | head -n 4
```

Expected output:

```
MAC: sha256, Iteration 2048
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
Certificate bag
```

That `PKCS7 Encrypted data` line is the certificate bags. `-nomacver` skips the integrity check but
does nothing about that encryption, so it does not let you read the certificates.

Certificates are only readable without the password when the archive was deliberately exported with
certificate encryption disabled:

*An archive whose certificates are deliberately left in the clear*

```bash
openssl pkcs12 -export -certpbe NONE -out open.p12 \
  -inkey private.key -in certificate.crt -passout pass:testpass
```

*Those certificates read without a password*

```bash
openssl pkcs12 -in open.p12 -nokeys -nomacver -passin pass: -out certs.pem
grep -c "BEGIN CERTIFICATE" certs.pem
```

> **Why -certpbe NONE is sometimes right**
>
> Certificates are public — there is nothing to hide in them, and encrypting them mainly makes an
>   archive harder to inspect. Some tooling exports this way deliberately so a chain can be read
>   without handing out the password. The private key remains encrypted either way; `-certpbe` does
>   not touch it.

## Building the chain file a server wants

```bash
cat certificate.crt chain.crt > fullchain.crt
```

Leaf first. That is the file nginx, Apache and HAProxy expect — see
[certificate chains](/concepts/certificate-chain/).

## Verify what you extracted

```bash
openssl x509 -in certificate.crt -noout -subject -issuer -dates -ext subjectAltName
```

*How many certificates ended up in the chain file?*

```bash
grep -c "BEGIN CERTIFICATE" chain.crt
```

## If OpenSSL 3 refuses the archive

```bash
openssl pkcs12 -legacy -in certificate.pfx -clcerts -nokeys -out certificate.crt
```

See [that error explained](/errors/unsupported-mac-pkcs12-legacy/).


## Frequently asked questions

### What is the difference between -clcerts and -cacerts?

`-clcerts` emits the client or end-entity certificate — the one for your hostname. `-cacerts` emits the CA certificates, meaning the intermediates. Running both gives you the two files a web server usually wants.

### Does -nokeys mean the key is not in the archive?

No. It means the key is not written to the output. The key is still inside the PFX; you have simply chosen not to extract it, which is the safer default when you do not need it.

### Why is the output empty?

Most often because the archive genuinely has no CA certificates in it, so `-cacerts` produces nothing. Run `openssl pkcs12 -info -noout` and count the certificate bags first.

### Can I skip the password?

The certificates are not encrypted, only the key is — but the archive's MAC still needs the password to verify. `-nomacver` skips that check and lets you read the certificates without it, at the cost of not detecting tampering.


## References

- [openssl-pkcs12(1)](https://docs.openssl.org/3.5/man1/openssl-pkcs12/) — -clcerts, -cacerts and -nokeys
- [RFC 7292: PKCS #12](https://www.rfc-editor.org/rfc/rfc7292) — the archive format, including the MAC OpenSSL 3 rejects on legacy files

## Related pages

- https://certguru.io/openssl/extract-key-from-pkcs12/
- https://certguru.io/convert/pfx-to-pem/
- https://certguru.io/formats/pkcs12-pfx-p12/
- https://certguru.io/errors/unsupported-mac-pkcs12-legacy/
- https://certguru.io/platforms/iis/

--
CertGuru — https://certguru.io
