Flutter解密PHP加密的AES文件报错:无效或损坏的填充块
问题解决思路
出现「Invalid argument(s): Invalid or corrupted pad block」错误的核心原因是PHP加密输出的密文格式与Flutter解密时的输入格式不匹配,结合两边代码分析,具体问题和解决步骤如下:
1. 密文格式不匹配(最关键)
PHP代码中,openssl_encrypt的第四个参数为0(默认值),此时函数会返回Base64编码后的字符串,而非原始二进制密文。你通过file_put_contents将这个Base64字符串写入了文件,而Flutter端直接读取文件字节并当作原始密文传入解密函数,导致密文格式完全错误,触发填充验证失败。
修正Flutter代码
需要先将文件读取的字节转成UTF-8字符串(还原PHP写入的Base64文本),再Base64解码得到原始密文字节:
final fileBytes = await File('$filePath').readAsBytes(); // 1. 将文件字节转成Base64编码的字符串 String base64Encrypted = utf8.decode(fileBytes); // 2. 解码得到原始密文字节 Uint8List encryptedBytes = base64.decode(base64Encrypted); var mykey = support['encryptionKey']; var myiv = '16charstring'; final keyString = Uint8List.fromList(sha256.convert(utf8.encode(mykey)).bytes); final ivString = Uint8List.fromList(sha256.convert(utf8.encode(myiv)).bytes.sublist(0, 16)); var iv = encrypt.IV(ivString); var encrypter = encrypt.Encrypter(encrypt.AES(encrypt.Key(keyString), mode: encrypt.AESMode.cbc)); final encrypted = encrypt.Encrypted(encryptedBytes); final decrypted = encrypter.decrypt(encrypted, iv: iv); return decrypted;
2. 额外验证点(避免其他潜在问题)
如果修正后仍报错,需逐一确认以下内容:
- 密钥一致性:确保Flutter中的
support['encryptionKey']与PHP中的$formationPurchased['encryption_key']是完全相同的字符串,包括大小写、特殊字符,且两边均使用UTF-8编码处理(当前代码已满足)。 - IV一致性:Flutter中的
myiv必须与PHP中的"16charstring"完全一致,无拼写错误或格式差异。 - 填充方式匹配:PHP的
openssl_encrypt默认使用PKCS7填充,Flutter的encrypt库中AES默认也使用PKCS7,两者无需额外修改即可匹配。
可选:修改PHP代码输出原始密文
如果允许修改PHP加密逻辑,也可以让openssl_encrypt直接输出原始二进制密文,这样Flutter端无需Base64解码,直接读取字节即可:
// 将第四个参数改为OPENSSL_RAW_DATA,输出原始密文字节 $encrypted = openssl_encrypt($content, 'aes-256-cbc', $this->key, OPENSSL_RAW_DATA, $this->iv); file_put_contents($tmp_file, $encrypted);
内容的提问来源于stack exchange,提问作者Tiruve
相关产品推荐
相关产品推荐

