digininja/DVWA · error · Exception
Decryption failed
Error message
Decryption failed
What it means
decrypt() wraps openssl_decrypt with cipher aes-128-ecb, the hard-coded key "ik ben een aardbei" and OPENSSL_PKCS1_PADDING, and throws this Exception whenever openssl returns false. ECB has no IV, so a false result means one of: the raw bytes (after hex2bin) were not produced with the same key, the ciphertext length is not a multiple of the 16-byte AES block, or the decrypted PKCS padding did not validate (corrupted or spliced ciphertext).
Source
Thrown at vulnerabilities/cryptography/source/medium.php:5
<?php
function decrypt ($ciphertext, $key) {
$e = openssl_decrypt($ciphertext, 'aes-128-ecb', $key, OPENSSL_PKCS1_PADDING);
if ($e === false) {
throw new Exception ("Decryption failed");
}
return $e;
}
$key = "ik ben een aardbei";
$errors = "";
$success = "";
$messages = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
try {
if (!array_key_exists ('token', $_POST)) {
throw new Exception ("No token passed");
} else {
$token = $_POST['token'];
if (strlen($token) % 32 != 0) {
throw new Exception ("Token is in wrong format");View on GitHub (pinned to 5d5c76cced)
Solutions
- Resubmit one of the three provided sample tokens unchanged to confirm the happy path decrypts.
- Verify the token is pure hex, even-length, and a multiple of 32 characters before submitting.
- When crafting your own token, encrypt with aes-128-ecb using the exact key "ik ben een aardbei" (PHP zero-pads it), then bin2hex() the raw ciphertext.
- Confirm the openssl extension is loaded and check the PHP error log for openssl warnings.
- Remember the decrypted plaintext must then be valid JSON or you hit the next exception.
Example fix
// before
$decrypted = decrypt(hex2bin ($token), $key);
// after
$raw = hex2bin($token);
if ($raw === false || strlen($raw) === 0 || strlen($raw) % 16 !== 0) {
throw new Exception("Token is in wrong format");
}
$decrypted = decrypt($raw, $key); Defensive patterns
Strategy: try-catch
Validate before calling
$token = trim($_POST['token'] ?? '');
if ($token === '' || !ctype_xdigit($token) || strlen($token) % 32 !== 0) {
$errors = 'Token is in wrong format';
} else {
$raw = hex2bin($token);
if ($raw === false || strlen($raw) % 16 !== 0) {
$errors = 'Token is in wrong format';
}
} Type guard
function isHexEncryptedToken(string $token): bool
{
return $token !== ''
&& ctype_xdigit($token)
&& strlen($token) % 32 === 0;
} Try / catch
try {
$decrypted = decrypt(hex2bin($token), $key);
} catch (Exception $e) {
// Distinguish crypto failure from transport/shape failures for actionable messages
error_log('Token decrypt failed: ' . $e->getMessage());
$errors = 'Token could not be decrypted with the expected key and mode.';
} Prevention
- Validate hex characters and block alignment before calling openssl_decrypt.
- Keep cipher, key, and encoding configuration in one place so producer and consumer cannot drift.
- Log openssl_error_string() when decrypt returns false to capture the concrete OpenSSL reason.
- Treat decrypt failure on user input as expected control flow, not a crash.
When it happens
Trigger: POSTing a hex token encrypted with a different key or mode (for example re-using the high-level key 'rainbowclimbinghigh'); submitting an empty token, which passes the % 32 length gate (0 % 32 == 0) and makes openssl_decrypt fail on empty input; hex containing non-hex characters so hex2bin yields garbage; block-splicing ECB blocks so the final block's padding no longer validates; raw ciphertext not a multiple of 16 bytes.
Common situations: Copy/paste truncation of the sample tokens; re-encrypting tokens externally (other languages reject or pad the 18-byte key differently from PHP's zero-padding, so cross-stack tokens fail); editing hex in editors that introduce smart quotes or whitespace; OpenSSL configuration differences between environments.
Related errors
- Decryption failed
- IV must be 16 bytes, {strlen($iv)} passed
- IV must be 12 bytes, {strlen($iv)} passed
- Decryption failed
- Could not decode JSON object.
AI-assisted analysis of digininja/DVWA@5d5c76cced (2026-08-21).
Data as JSON: /api/errors/58f17e6bf148829d.
Report an issue: GitHub.