You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mcrypt_encrypt加密时报Encryption mode requires an initialization vector of size 16错误如何解决

问题原因

  • CBC(密码分组链接)加密模式要求必须搭配初始化向量(IV)使用,你使用的MCRYPT_RIJNDAEL_128算法对应IV长度要求为16字节,原代码未传入IV参数,因此触发警告且加密失败返回空。
  • 额外注意:mcrypt扩展自PHP 7.1起已被官方废弃,PHP 7.2及以上版本默认不再内置该扩展,生产环境更推荐使用openssl扩展实现对称加密。

修复方案(适配原有mcrypt逻辑)

首先生成符合要求的16字节随机IV,传入mcrypt_encrypt的第5个参数即可。解密时必须使用相同的IV才能正常解密,因此通常会将IV直接拼接在密文前存储/传输,解密时先取出前16位作为IV即可。
修复后的代码:

<?php
$str = "hassan";
$key = "WKSaRVxscxa7eDrX0mLjU6OUphS6F1z0";

$block = 16;
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);

// 生成16字节随机IV
$iv = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);

// 传入IV参数加密
$encrypted = base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_CBC, $iv));

var_dump($encrypted);

配套解密参考逻辑:

<?php
$encrypted = base64_decode($加密后的字符串);
// 取出前16位为IV
$iv = substr($encrypted, 0, 16);
// 剩余部分为密文
$ciphertext = substr($encrypted, 16);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC, $iv);
// 移除PKCS7填充
$pad = ord($decrypted[$strlen = strlen($decrypted) - 1]);
$decrypted = substr($decrypted, 0, $strlen - $pad);

更推荐的openssl实现方案(兼容PHP7+所有版本)

如果你的运行环境已经不支持mcrypt,可直接使用openssl扩展实现同等的AES-128-CBC加密,无需手动处理填充:

<?php
$str = "hassan";
$key = "WKSaRVxscxa7eDrX0mLjU6OUphS6F1z0";
$iv = openssl_random_pseudo_bytes(16);
// 加密
$encrypted = base64_encode($iv . openssl_encrypt($str, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv));
var_dump($encrypted);

// 解密逻辑
$encrypted = base64_decode($encrypted);
$iv = substr($encrypted, 0, 16);
$ciphertext = substr($encrypted, 16);
$decrypted = openssl_decrypt($ciphertext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
var_dump($decrypted);

内容的提问来源于stack exchange,提问作者Muhammad Hassan Javed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:39:04