{"record":{"id":"cd66ca1532f03750","repo":"w7corp/easywechat","slug":"decrypt-aes-cbc-error","errorCode":null,"errorMessage":"Decrypt AES CBC error.","messagePattern":"Decrypt AES CBC error\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Kernel/Support/AesCbc.php","lineNumber":44,"sourceCode":"\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\n        if ($plaintext === false) {\n            throw new InvalidArgumentException(openssl_error_string() ?: 'Decrypt AES CBC error.');\n        }\n\n        return $plaintext;\n    }\n}\n","sourceCodeStart":26,"sourceCodeEnd":50,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/Kernel/Support/AesCbc.php#L26-L50","documentation":"Support\\AesCbc::decrypt() returns false from openssl_decrypt (bad key, bad IV, or corrupted ciphertext) and throws InvalidArgumentException with openssl_error_string() or the fallback 'Decrypt AES CBC error.'. In EasyWeChat this helper backs MiniApp\\Decryptor::decrypt(), which rewraps the failure as DecryptException('The given payload is invalid: ...') — the classic symptom of a wrong or expired WeChat session_key when decrypting wx.getUserProfile / phone-number payloads.","triggerScenarios":"Calling MiniApp Decryptor::decrypt($sessionKey, $iv, $encryptedData) where session_key is stale (user re-logged-in elsewhere, rotating the key) or does not match the code2session result used to fetch it; or the iv/encryptedData came from a different client call than the session_key.","commonSituations":"Cached session_key reused after the user logged in again (keys rotate per login), dev/prod appid mismatch, env or openid-keyed cache returning another user's key, passing base64 values undecoded.","solutions":["Re-run the login flow (code2session) to obtain a fresh session_key, store it keyed by openid, then retry the decrypt","Confirm iv and encryptedData come from the same client invocation (e.g. the same getPhoneNumber/getUserProfile result) as the session_key","Check the wrapped message: DecryptException text includes the underlying reason from openssl_error_string()"],"exampleFix":"// before\n$payload = Decryptor::decrypt($cachedSessionKey, $iv, $encryptedData); // DecryptException\n\n// after\ntry {\n    $payload = Decryptor::decrypt($cachedSessionKey, $iv, $encryptedData);\n} catch (DecryptException $e) {\n    // session_key likely rotated: force re-login on the mini program side\n    $session = $api->get('/sns/jscode2session', [...]);\n    $cachedSessionKey = $session['session_key'];\n    $payload = Decryptor::decrypt($cachedSessionKey, $iv, $encryptedData);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use EasyWeChat\\Kernel\\Exceptions\\DecryptException;\n\ntry {\n    $payload = \\EasyWeChat\\MiniApp\\Decryptor::decrypt($sessionKey, $iv, $encryptedData);\n} catch (DecryptException $e) {\n    // session_key rotated or mismatched: re-run code2session and retry once\n    $newSessionKey = $this->refreshSessionKey($openid); // your code2session wrapper\n    if ($newSessionKey !== null && $newSessionKey !== $sessionKey) {\n        $payload = \\EasyWeChat\\MiniApp\\Decryptor::decrypt($newSessionKey, $iv, $encryptedData);\n    } else {\n        throw $e; // genuinely corrupt payload\n    }\n}","preventionTips":["Store session_key keyed by openid with a short TTL and refresh it on every successful code2session","Treat DecryptException as a signal to re-authenticate the mini-program user, not as a hard failure","Ensure iv and encryptedData are forwarded from the same client API call that produced the session_key"],"tags":["php","easywechat","miniprogram","encryption","session-key","aes"],"backgroundTag":"session-key-mismatch","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}