php判断加密字符串长度_php加密后长度变化检测【步骤】

8次阅读

php加密函数输出长度由算法、密钥、填充和编码共同决定:md5()恒32字符,sha1()恒40,sha256()恒64;password_hash()用bcrypt时恒60字符,argon2id则96–120字符不等;openssl_encrypt()输出二进制,需base64或hex编码后才可安全测长,且须校验结构合法性。

php判断加密字符串长度_php加密后长度变化检测【步骤】

PHP中常见加密函数输出长度规律

加密后的字符串长度不是随机的,而是由算法、密钥、填充方式和编码格式共同决定。直接用 strlen() 测长度没问题,但必须清楚底层逻辑,否则会误判“加密失败”或“数据截断”。

  • md5() 固定输出 32 字符(十六进制),sha1() 是 40 字符,sha256() 是 64 字符 —— 这些是哈希,不可逆,且长度恒定
  • password_hash() 使用 bcrypt 时默认输出 60 字符;改用 argon2id 则长度不固定(通常 96–120 字符),取决于参数
  • 对称加密如 openssl_encrypt() 输出的是二进制数据,若未用 base64_encode()bin2hex() 编码,直接 strlen() 会出错(含 字节

检测加密字符串是否被意外截断

数据库字段太短、http 参数截断、日志自动 truncation 都会导致加密串损坏。不能只看长度“是不是预期值”,还要验证结构合法性。

  • password_hash() 输出,用 password_get_info() 检查是否返回有效数组,而非空或 false
  • 对 base64 编码的密文,先用 base64_decode($str, true) 的 strict 模式解码,返回 false 说明格式非法(不只是长度不对)
  • 对 hex 字符串(如 bin2hex() 结果),用 ctype_xdigit() + strlen() 双重校验:长度为偶数且全为 0-9a-f

openssl_encrypt() 后长度计算容易踩的坑

很多人以为 openssl_encrypt() 输出长度 = 明文长度 + 填充,实际还受 IV、模式、编码影响。

  • 使用 CBC 模式时,输出长度一定是 block size(如 AES-128 是 16 字节)的整数倍;原始明文 1 字节也会变成 16 字节
  • 如果调用后直接 strlen(),得到的是二进制长度;若存数据库或传 API,大概率用了 base64_encode(),此时长度 ≈ ceil(密文字节数 * 4 / 3)
  • IV 不参与加密输出,但必须和密文一起保存;若只存密文而丢 IV,解密必然失败——这不是长度问题,但常被误认为“密文损坏”

写入前做长度防御性检查的实用代码

别等报错才处理,入库或序列化前主动拦截异常长度。

立即学习PHP免费学习笔记(深入)”;

// 示例:校验 password_hash 输出 $hash = password_hash('123', PASSWORD_ARGON2ID); if (empty($hash) || strlen($hash) < 96 || !password_get_info($hash)['algo']) {     throw new InvalidArgumentException('Invalid hash generated'); } 

// 示例:校验 base64 编码的 openssl 密文 $ciphertext = base64_encode(openssl_encrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv)); if (!base64_decode($ciphertext, true) || strlen($ciphertext) % 4 !== 0) { throw new RuntimeException('Ciphertext corrupted or improperly encoded'); }

真正麻烦的不是长度本身,而是不同环节对“长度”的理解不一致:数据库 varchar(255) 存的是字符数,但 base64 编码后每 4 字符对应 3 字节原始密文——这个换算关系,漏掉一次就可能让整个加密链路失效。

text=ZqhQzanResources