# OpenSSL 3 cannot read my PFX

If OpenSSL 3 fails to open a `.pfx` or `.p12` with a MAC error, an "unsupported" decoder message, or an apparent wrong-password error, the cause is almost always the algorithm rather than the password. OpenSSL 3 moved RC2, 3DES and other legacy ciphers into a provider that is not loaded by default, and older Windows and Java tools wrote archives using exactly those. Add `-legacy` to the command — `openssl pkcs12 -legacy -in certificate.pfx -out certificate.pem -nodes`. The same flag on export produces archives those older tools can read.

Source: https://certguru.io/errors/unsupported-mac-pkcs12-legacy/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

> **What it looks like**
>
> ```
>   Mac verify error: invalid password?
>   ```
>   ```
>   error:0308010C:digital envelope routines::unsupported
>   ```
>   On Windows: *"The password you entered is incorrect."* On Java:
>   `unrecognized algorithm name: PBEWithSHA1AndRC2_40`.

## What actually changed

OpenSSL 3.0 reorganised algorithms into **providers**. Ciphers considered obsolete — RC2, RC4,
3DES-in-PKCS#12, MD2, and others — moved into a `legacy` provider that is **not loaded by default**.

At the same time, the default PKCS#12 export encryption became AES-256-CBC with PBKDF2 and a
SHA-256 MAC.

The result is a two-way incompatibility:

| Archive written by | Read by OpenSSL 3 | Read by older tools |
| --- | --- | --- |
| OpenSSL 1.x, older Windows, older Java | Fails without `-legacy` | Fine |
| OpenSSL 3 defaults | Fine | Fails, usually reported as a bad password |

## Reading an old archive

*Load the legacy provider for this command only*

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

If that works where the command without `-legacy` failed, you have confirmed the diagnosis. Then
extract as normal:

```bash
openssl pkcs12 -legacy -in certificate.pfx -nocerts -nodes -out private.key
openssl pkcs12 -legacy -in certificate.pfx -clcerts -nokeys -out certificate.crt
```

## Writing an archive an old tool can read

*Export using legacy algorithms*

```bash
openssl pkcs12 -export -legacy \
  -out certificate.pfx \
  -inkey private.key -in certificate.crt -certfile chain.crt
```

If your build does not accept `-legacy`, name the algorithms explicitly:

```bash
openssl pkcs12 -export \
  -certpbe PBE-SHA1-3DES \
  -keypbe PBE-SHA1-3DES \
  -macalg sha1 \
  -out certificate.pfx \
  -inkey private.key -in certificate.crt -certfile chain.crt
```

## Telling which encryption an archive uses

```bash
openssl pkcs12 -in certificate.pfx -info -noout 2>&1 | head -n 5
```

Expected output:

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

`AES-256-CBC` and a `sha256` MAC mean a modern archive. `RC2-40-CBC` or `3DES` with a `sha1` MAC
mean a legacy one.

## The better long-term fix

`-legacy` is a compatibility shim, not a resting place. Where you can:

1. **Upgrade the consuming system.** Windows Server 2019 and later, and JDK 8u301 and later, read
   AES-256 PKCS#12 archives without complaint.
2. **Avoid PKCS#12 for transport.** If both ends are Unix, moving separate PEM files sidesteps the
   entire problem.
3. **Re-protect at the destination.** If you must use `-legacy` to move a key, do not leave it in
   that archive afterwards.

> **RC2 is not a secure cipher**
>
> A `-legacy` archive is protected by 40-bit or 128-bit RC2, or 3DES. Treat such a file as barely
>   protected: move it over a secure channel, do not leave copies around, and delete it once
>   imported.

## Loading the provider globally (usually a mistake)

It can be done through `openssl.cnf`:

```ini
[provider_sect]
default = default_sect
legacy  = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1
```

> **Prefer the per-command flag**
>
> Activating the legacy provider machine-wide silently re-enables weak algorithms for every
>   operation, including ones where you would want OpenSSL to refuse. A `-legacy` flag on the one
>   command that needs it keeps the exception visible.


## Frequently asked questions

### Does -legacy weaken the file?

Yes. It selects RC2 or 3DES with a SHA-1 MAC, all of which are deprecated. Use it only when the system on the other end cannot read a modern archive, treat the file as short-lived transport, and protect the key properly at the destination.

### Why does Windows say the password is wrong when it is correct?

Because the older Windows importer cannot decrypt an AES-256-CBC archive, and it reports every decryption failure as a bad password. The symptom points at the wrong cause, which is why this wastes so much time.

### Which OpenSSL versions are affected?

OpenSSL 3.0 and later. OpenSSL 1.1.1 and earlier used RC2/3DES by default and had no separate legacy provider, so they read and write the old format without any flag.

### Can I load the legacy provider permanently?

Yes, by adding a legacy provider section to openssl.cnf, but it is better not to. A per-command `-legacy` flag keeps the weak algorithms opt-in rather than making every operation on the machine quietly accept them.


## References

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

## Related pages

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

--
CertGuru — https://certguru.io
