phalcon/cphalcon · error · InvalidDecryptLength
The provided input is too short for the selected cipher.
Error message
The provided input is too short for the selected cipher.
What it means
Before decrypting, Crypt verifies the ciphertext is at least as long as the cipher's IV (openssl_cipher_iv_length for the configured cipher). Input shorter than that cannot possibly contain IV + data, so it throws InvalidDecryptLength without attempting decryption. This guards the mb_substr() extraction of the IV from producing garbage or an empty string.
Source
Thrown at phalcon/Encryption/Crypt.zep:239
var blockSize, cipher, cipherText, decrypted, decryptKey, digest,
hashAlgorithm, hashLength, iv, ivLength, mode;
let decryptKey = this->key;
if true !== empty(key) {
let decryptKey = key;
}
if true === empty(decryptKey) {
throw new EmptyDecryptionKey();
}
let cipher = this->cipher,
ivLength = this->ivLength;
this->checkCipherHashIsAvailable(cipher, "cipher");
if true !== this->isValidDecryptLength(input) {
throw new InvalidDecryptLength();
}
let mode = this->getMode(),
blockSize = this->getBlockSize(mode),
iv = mb_substr(input, 0, ivLength, "8bit");
/**
* Check if we have chosen signing and use the hash
*/
let digest = "",
hashAlgorithm = this->getHashAlgorithm();
if true === this->useSigning {
if !fetch hashLength, this->hashLengthCache[hashAlgorithm] {
let hashLength = strlen(this->phpHash(hashAlgorithm, "", true));
let this->hashLengthCache[hashAlgorithm] = hashLength;
}
let digest = mb_substr(input, ivLength, hashLength, "8bit"),
cipherText = mb_substr(input, ivLength + hashLength, null, "8bit");View on GitHub (pinned to b7419de9cd)
Solutions
- Match the API pair: if data was produced with encryptBase64(), decrypt with decryptBase64().
- Sanity-check before calling: $crypt->isValidDecryptLength($input) (public method) - it applies exactly this check.
- Transport ciphertext as base64 (use encryptBase64) or raw-binary-safe (POST body, not URL params) to prevent truncation/corruption.
- If input is legitimately empty (optional field), branch on empty($input) and skip decryption instead of calling decrypt('').
Example fix
// before
$plain = $crypt->decrypt($request->getQuery('t', 'string')); // truncated by URL transport
// after
$token = $request->getQuery('t', 'string');
if ($token === null || !$crypt->isValidDecryptLength($token)) {
throw new \InvalidArgumentException('Malformed or missing token');
}
$plain = $crypt->decrypt($token); Defensive patterns
Strategy: validation
Validate before calling
if ('' === $payload || !$crypt->isValidDecryptLength($payload)) {
throw new \InvalidArgumentException('Payload missing or shorter than the cipher IV');
}
$plain = $crypt->decrypt($payload); Type guard
function isPlausibleCipherText(\Phalcon\Encryption\Crypt $crypt, string $payload): bool
{
return '' !== $payload && $crypt->isValidDecryptLength($payload);
} Try / catch
try {
$plain = $crypt->decrypt($payload);
} catch (\Phalcon\Encryption\Crypt\Exception\InvalidDecryptLength $e) {
// treat as malformed input, not a 500 - reject the request/token
return $response->setStatusCode(400, 'Bad Request')->setContent('Invalid token');
} Prevention
- Pair encrypt/decrypt with encryptBase64/decryptBase64 and never mix raw and base64 forms.
- Branch on empty input before decrypting optional fields.
- Transport ciphertext via base64 in JSON/POST bodies, not raw URL parameters.
When it happens
Trigger: Calling decrypt() on: an empty string; a truncated payload; data that was never encrypted by this class (plain text, JSON); a base64 string when you meant to use decryptBase64(); or ciphertext produced with a different cipher whose IV length is larger.
Common situations: Passing base64-wrapped payloads (Crypt produces raw binary; encryptBase64/decryptBase64 are the matching pair) - base64 text of a short message can still be longer than the IV and instead fail later with Mismatch, but a short one fails here. Empty DB columns, truncated URL parameters (binary data mangled by GET transport), and switching ciphers between encrypt and decrypt are typical causes.
Related errors
- Could not decrypt data
- Decryption key cannot be empty
- Hash does not match.
- Encryption key cannot be empty
- Cannot calculate Random Pseudo Bytes
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/a403936e20fd6772.
Report an issue: GitHub.