{"record":{"id":"babaad77e79815b9","repo":"phalcon/cphalcon","slug":"encryption-key-cannot-be-empty","errorCode":null,"errorMessage":"Encryption key cannot be empty","messagePattern":"Encryption key cannot be empty","errorType":"exception","errorClass":"EmptyEncryptionKey","httpStatus":null,"severity":"error","filePath":"phalcon/Encryption/Crypt.zep","lineNumber":337,"sourceCode":"     *\n     * @param string      $input\n     * @param string|null $key\n     *\n     * @return string\n     * @throws Exception\n     */\n    public function encrypt(string input, string key = null) -> string\n    {\n        var blockSize, cipher, digest, encryptKey, encrypted, iv, ivLength,\n            mode, padded;\n\n        let encryptKey = this->key;\n        if true !== empty(key) {\n            let encryptKey = key;\n        }\n\n        if true === empty(encryptKey) {\n            throw new EmptyEncryptionKey();\n        }\n\n        let cipher   = this->cipher,\n            ivLength = this->ivLength;\n\n        this->checkCipherHashIsAvailable(cipher, \"cipher\");\n\n        let mode      = this->getMode(),\n            blockSize = this->getBlockSize(mode);\n\n        try {\n            let iv = this->phpOpensslRandomPseudoBytes(ivLength);\n        } catch \\Throwable {\n            throw new RandomBytesGenerationFailed();\n        }\n\n        let padded = this->encryptGetPadded(mode, input, blockSize);\n","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Encryption/Crypt.zep#L319-L355","documentation":"Crypt::encrypt() needs a key: the second argument if given, otherwise the one set via setKey(). If both are empty it throws EmptyEncryptionKey before generating an IV. Like its decrypt twin, this is a hard configuration failure - Phalcon refuses to encrypt with no key rather than silently using empty material.","triggerScenarios":"new Crypt() followed directly by encrypt($data); setKey('') then encrypt($data) without the second argument; a DI-shared Crypt whose key is injected from an empty config/env value in this environment.","commonSituations":"Missing APP_KEY-style env var in CI, Docker, or a new developer's .env; config cached before the key existed; key value loaded with a wrong config path so it resolves to null and casts to empty string.","solutions":["Set the key at construction time in your DI setup: $crypt->setKey($config->encryption->key) after asserting it is non-empty.","Or pass it per call: $crypt->encrypt($data, $key).","Add a boot-time assertion: if (empty($_ENV['APP_ENCRYPTION_KEY'])) { throw new RuntimeException('Encryption key missing'); } so the app fails fast.","Generate the key with bin2hex(random_bytes(32)) once and store it in a secret manager/env - never derive it from a password."],"exampleFix":"// before\n$di->set('crypt', function () {\n    $crypt = new \\Phalcon\\Encryption\\Crypt();\n    return $crypt; // key never configured\n});\n$stored = $di->get('crypt')->encrypt($secret); // throws\n\n// after\n$di->set('crypt', function () use ($config) {\n    $key = $config->path('encryption.key');\n    if (empty($key)) {\n        throw new \\RuntimeException('encryption.key is not configured');\n    }\n    return (new \\Phalcon\\Encryption\\Crypt())->setKey($key);\n});","handlingStrategy":"validation","validationCode":"$key = $_ENV['APP_ENCRYPTION_KEY'] ?? '';\nif ('' === $key) {\n    throw new \\RuntimeException('APP_ENCRYPTION_KEY is not set');\n}\n$crypt->setKey($key);\n$cipherText = $crypt->encrypt($data);","typeGuard":"function hasCryptKey(\\Phalcon\\Encryption\\Crypt $crypt): bool\n{\n    return '' !== $crypt->getKey();\n}","tryCatchPattern":"try {\n    $stored = $crypt->encrypt($data);\n} catch (\\Phalcon\\Encryption\\Crypt\\Exception\\EmptyEncryptionKey $e) {\n    throw new \\RuntimeException('Cannot encrypt: no key configured', 0, $e);\n}","preventionTips":["Derive the exact-length key once at boot and inject the configured Crypt from DI everywhere.","Add a startup check that both reads and encrypts a probe string - it exercises the full path.","Never silently skip encryption when the key is missing; storing plaintext as a fallback defeats the control."],"tags":["phalcon","crypt","encryption","key-management","configuration"],"backgroundTag":"empty-encryption-key","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}