{"record":{"id":"3b02be1cbb1e84fb","repo":"w7corp/easywechat","slug":"encrypt-aes-cbc-error","errorCode":null,"errorMessage":"Encrypt AES CBC error.","messagePattern":"Encrypt AES CBC error\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Kernel/Support/AesCbc.php","lineNumber":24,"sourceCode":"\nuse EasyWeChat\\Kernel\\Contracts\\Aes;\nuse EasyWeChat\\Kernel\\Exceptions\\InvalidArgumentException;\n\nuse function base64_decode;\nuse function openssl_decrypt;\nuse function openssl_error_string;\n\nclass AesCbc implements Aes\n{\n    /**\n     * @throws InvalidArgumentException\n     */\n    public static function encrypt(string $plaintext, string $key, ?string $iv = null): string\n    {\n        $ciphertext = \\openssl_encrypt($plaintext, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, (string) $iv);\n\n        if ($ciphertext === false) {\n            throw new InvalidArgumentException(openssl_error_string() ?: 'Encrypt AES CBC error.');\n        }\n\n        return base64_encode($ciphertext);\n    }\n\n    /**\n     * @throws InvalidArgumentException\n     */\n    public static function decrypt(string $ciphertext, string $key, ?string $iv = null): string\n    {\n        $plaintext = openssl_decrypt(\n            base64_decode($ciphertext),\n            'aes-128-cbc',\n            $key,\n            OPENSSL_RAW_DATA,\n            (string) $iv\n        );\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/Kernel/Support/AesCbc.php#L6-L42","documentation":"Support\\AesCbc::encrypt() runs openssl_encrypt with the fixed 'aes-128-cbc' cipher and OPENSSL_RAW_DATA; when openssl returns false it throws InvalidArgumentException carrying openssl_error_string() (e.g. 'key length not allowed') or the fallback 'Encrypt AES CBC error.'. AES-128-CBC requires a raw 16-byte key and a 16-byte IV, so any other key length fails.","triggerScenarios":"Encrypting with a key that is not 16 raw bytes — passing a base64- or hex-encoded key without decoding, a 32-byte key (that would be AES-256), or an empty/short IV.","commonSituations":"Reusing a key material meant for aes-256, forgetting base64_decode() on stored keys, deriving keys with hash('sha256') (32 bytes) instead of md5 (16 bytes).","solutions":["Provide exactly 16 raw bytes as the key (base64_decode it first if it is stored encoded) and a 16-byte IV","When it throws, log openssl_error_string() — it states the precise reason (usually key length)","If your key is 32 bytes, switch to an AES-256 cipher implementation instead of forcing AesCbc"],"exampleFix":"// before\n$cipher = AesCbc::encrypt($plain, $base64Key, $base64Iv); // encoded strings -> wrong lengths\n\n// after\n$cipher = AesCbc::encrypt(\n    $plain,\n    base64_decode($base64Key),\n    base64_decode($base64Iv)\n);","handlingStrategy":"validation","validationCode":"// Assert key/iv lengths before encrypting (aes-128-cbc)\nif (strlen($key) !== 16) {\n    throw new InvalidArgumentException('AesCbc key must be 16 bytes, got '.strlen($key));\n}\nif (strlen((string) $iv) !== 16) {\n    throw new InvalidArgumentException('AesCbc iv must be 16 bytes, got '.strlen((string) $iv));\n}\n$ciphertext = AesCbc::encrypt($plaintext, $key, $iv);","typeGuard":"function isRawAes128Key(string $key): bool\n{\n    return strlen($key) === 16;\n}","tryCatchPattern":"try {\n    $ciphertext = AesCbc::encrypt($plaintext, $key, $iv);\n} catch (\\EasyWeChat\\Kernel\\Exceptions\\InvalidArgumentException $e) {\n    // openssl_error_string() in the message states the reason (usually key length)\n    throw new InvalidArgumentException('AES-CBC encrypt failed: '.$e->getMessage(), 0, $e);\n}","preventionTips":["Store keys pre-decoded (raw bytes) or always decode at one boundary","Unit-test key length at config load time, not inside request handlers"],"tags":["php","easywechat","encryption","aes","openssl"],"backgroundTag":"invalid-aes-key","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}