# bad decrypt

The OpenSSL error "bad decrypt" means decryption ran to completion and the padding check at the end failed, which is what happens when the key derived from the supplied passphrase does not match the key the data was encrypted with. For an encrypted private key that means the passphrase is wrong. For a file encrypted with `openssl enc` it very often means the passphrase is right but the key derivation differs — OpenSSL 1.0.x derived keys using MD5 and OpenSSL 1.1.0 and later default to SHA-256, so a file encrypted by an older OpenSSL only decrypts on a newer one when `-md md5` is supplied. OpenSSL 3 reports the condition as `error:1C800064:Provider routines::bad decrypt`, where OpenSSL 1.1.1 wrote `error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt`.

Source: https://certguru.io/errors/bad-decrypt/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

> **The exact message**
>
> ```
>   error:1C800064:Provider routines::bad decrypt
>   ```
>   OpenSSL 1.1.1 and earlier wrote the same condition as
>   `error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt`.

## What the error actually means

Decryption did not fail early. OpenSSL read the whole ciphertext, decrypted it, and then checked the
padding on the final block — which is the last step, and the first point at which a wrong key
becomes detectable at all.

That is the useful part of the message: the key OpenSSL derived from your passphrase is not the key
the data was encrypted with. Either the passphrase is different, or the derivation is.

> **Two very different situations produce it**
>
> A wrong passphrase on a **private key** and a version-skewed **`openssl enc` file** both land here.
>   The second is the one people lose an afternoon to, because the passphrase really is correct.

## Case 1 — an encrypted private key

The file begins with a `BEGIN ENCRYPTED PRIVATE KEY` line, or with `BEGIN RSA PRIVATE KEY` followed
by a `Proc-Type` and `DEK-Info` header. Test the passphrase without touching the file:

*Does this passphrase open the key?*

```bash
openssl pkey -in encrypted.key -passin pass:testpass -noout
```

Silence and a zero exit status mean the passphrase is right. `bad decrypt` means it is not, and
there is no way around that — the check is the encryption doing its job.

> **Shell quoting is a real cause here**
>
> A passphrase containing `$`, `!`, backticks or spaces is rewritten by the shell before OpenSSL sees
>   it. `-passin pass:P@ss$word` sends `P@ss` plus an empty variable. Use single quotes, or better,
>   `-passin file:passphrase.txt` so the shell never touches it.

Once it opens, [remove the passphrase](/openssl/remove-passphrase-from-key/) or change it:

*Re-encrypt under a new passphrase*

```bash
openssl pkey -in encrypted.key -passin pass:testpass \
  -aes256 -passout pass:newpassphrase -out rekeyed.key
```

## Case 2 — a file encrypted with openssl enc

This is the version-skew case, and the symptom is distinctive: the passphrase is definitely correct,
the file used to open, and something on the machine changed.

OpenSSL 1.0.x derived the encryption key from the passphrase using **MD5**. OpenSSL 1.1.0 changed
that default to **SHA-256**. The passphrase is unchanged; the key derived from it is completely
different, so the padding check fails and you get `bad decrypt`.

*Decrypt a file written by OpenSSL 1.0.x*

```bash
openssl enc -d -aes-256-cbc -md md5 -in secret.enc -out secret.txt
```

Once it opens, re-encrypt it properly. `-pbkdf2` replaces the legacy derivation with PBKDF2 and is
the reason OpenSSL 3 prints a deprecation warning when it is absent:

*Round-trip with modern derivation*

```bash
openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt \
  -in certificate.crt -out certificate.enc -pass pass:testpass
openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 \
  -in certificate.enc -out certificate.dec -pass pass:testpass
```

## Every option must match on both sides

`enc` stores the salt in the file but nothing else. Cipher, digest, iteration count and whether
PBKDF2 was used are all remembered by you, not by the file, and any one of them being different
produces this identical error:

| Encrypted with | Decrypt needs |
| --- | --- |
| `-aes-256-cbc` | `-aes-256-cbc` — a different cipher fails here |
| OpenSSL ≤ 1.0.2, no `-md` | `-md md5` |
| OpenSSL ≥ 1.1.0, no `-md` | nothing extra; SHA-256 is the default |
| `-pbkdf2` | `-pbkdf2` |
| `-pbkdf2 -iter 600000` | `-pbkdf2 -iter 600000` — the count is not stored |
| `-nosalt` | `-nosalt` |

> **Read the header before guessing**
>
> A salted `enc` file starts with the ASCII bytes `Salted__` followed by eight bytes of salt. If
>   those bytes are absent, the file was written with `-nosalt` and every decrypt attempt without that
>   flag will fail this way.

*Is the file salted?*

```bash
head -c 8 certificate.enc | od -c | head -1
```

## What this error is not

> **A wrong PKCS#12 password looks different**
>
> A `.pfx` or `.p12` opened with the wrong password reports
>   `Mac verify error: invalid password?`, because PKCS#12 carries an integrity MAC that fails before
>   any decryption happens. If that is your message, and especially if OpenSSL 3 is refusing a file
>   Windows produced, go to
>   [PKCS#12 unsupported and MAC errors](/errors/unsupported-mac-pkcs12-legacy/) instead.

Nor is it a PEM parsing failure. A file whose armour is malformed fails much earlier, with
[PEM routines::no start line](/errors/pem-routines-no-start-line/) — that error means OpenSSL never
found data to decrypt, where this one means it decrypted and the result was wrong.


## Frequently asked questions

### Does bad decrypt mean the file is corrupt?

Rarely. Decryption reached the end of the data and the padding did not check out, which is the expected outcome of a wrong key rather than of damaged bytes. Truncated or corrupted input more often produces a length or format error earlier in the process.

### Why did a file encrypted last year stop opening after an OpenSSL upgrade?

OpenSSL 1.1.0 changed the default key-derivation digest from MD5 to SHA-256. The passphrase is unchanged and correct; the key derived from it is not. Add `-md md5` to decrypt the old file, then re-encrypt it with `-pbkdf2`.

### My PKCS#12 file fails. Is this the same error?

No. A wrong PKCS#12 password produces `Mac verify error: invalid password?`, and OpenSSL 3 refusing a legacy PKCS#12 algorithm produces an unsupported-algorithm error. Both are covered on PKCS#12 unsupported and MAC errors.

### Can I recover the data if the passphrase is genuinely lost?

No. That is the property the encryption exists to provide. For a private key, the only path forward is to generate a new key, issue a new CSR and have a replacement certificate issued.

### What does the deprecated key derivation warning mean?

OpenSSL 3 prints it whenever `enc` is used without `-pbkdf2`, because the legacy `EVP_BytesToKey` derivation is weak against brute force. It is a warning about the file you are creating, not a cause of this error.


## References

- [openssl-enc(1)](https://docs.openssl.org/3.5/man1/openssl-enc/) — the -md, -pbkdf2 and -iter options and their defaults
- [openssl-pkey(1)](https://docs.openssl.org/3.5/man1/openssl-pkey/) — reading and re-encrypting an encrypted private key
- [RFC 8018: PKCS #5 password-based cryptography](https://www.rfc-editor.org/rfc/rfc8018) — PBKDF2, and why the derivation parameters must match on both sides

## Related pages

- https://certguru.io/errors/unsupported-mac-pkcs12-legacy/
- https://certguru.io/openssl/remove-passphrase-from-key/
- https://certguru.io/formats/key/
- https://certguru.io/errors/pem-routines-no-start-line/
- https://certguru.io/formats/pkcs8/
- https://certguru.io/openssl/generate-private-key/

--
CertGuru — https://certguru.io
