PHP 从 MCRYPT_MODE_ECB 切换到 AES-256-ECB
Posted
技术标签:
【中文标题】PHP 从 MCRYPT_MODE_ECB 切换到 AES-256-ECB【英文标题】:PHP switch from MCRYPT_MODE_ECB to AES-256-ECB 【发布时间】:2018-07-22 10:00:26 【问题描述】:我正在重写代码以兼容 php 7.2。旧代码是
public function encryptPasswordOld($password, $salt)
$key = md5($salt);
$result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $password, MCRYPT_MODE_ECB);
return base64_encode($result);
根据我的研究,新代码应该是这样的
public function encryptPasswordNew($password, $salt)
$method = 'AES-256-ECB';
$ivSize = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivSize);
$key = md5($salt);
$result = openssl_encrypt($password, $method, $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($result);
但我尝试了 openssl_encrypt 选项的所有组合:OPENSSL_RAW_DATA
、OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
、OPENSSL_ZERO_PADDING
、0
,但由于旧方法返回,结果仍然不同
【问题讨论】:
见Use openssl_encrypt to replace Mcrypt for 3DES-ECB encryption、Can't decrypt using pgcrypto from AES-256-CBC but AES-128-CBC is OK、MCrypt rijndael-128 to OpenSSL aes-128-ecb conversion等。另见Upgrading my encryption library from Mcrypt to OpenSSL、Replace Mcrypt with OpenSSL和Preparing for removal of Mcrypt in PHP 7.2 @jww - 根据您的一些链接,我认为我做得对,人们使用的是 AES-128-ECB,...但我使用的是 AES-256-ECB 但仍然错误结果 对我来说,旧的看起来有点弯曲/破碎。 MD5 生成 128 位的摘要。它太短而不能用于需要 256 位的 AES-256 密钥。你知道 Mcrypt 是否会自动回填 0 吗?将来,使用HKDF 提取密码熵并扩展AES-256 密钥的熵。 另外,对于openssl_encrypt
,您可能需要关闭 PKCS 填充。另请参阅 OpenSSL wiki 上的 EVP Symmetric Encryption and Decryption | Padding。我不知道如何使用 Mcrypt 或 PHP 来做到这一点。 mcrypt-encrypt
页面确实说:“OpenSSL 还使用 PKCS7 填充和 CBC 模式,而不是 mcrypt 的 NULL 字节填充。因此,与 OpenSSL 相比,mcrypt 更可能使您的代码容易受到填充 oracle 攻击。”
【参考方案1】:
尝试在加密前对值使用 pkcs5padding。即
记住块大小应该基于 8 字节,即 8/16/24 等。
function pkcs5_pad($text, $blocksize)
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr(0), $pad);
和加密选项应该是 OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,即
openssl_encrypt(pkcs5_pad($value, 16), 'aes-256-ecb', $aes_key, 3, '')
【讨论】:
ecb 不推荐使用,它将文本分成段并在没有任何上下文信息的情况下对每个段进行加密,与 cbc 模式相比,解密“相当容易”。以上是关于PHP 从 MCRYPT_MODE_ECB 切换到 AES-256-ECB的主要内容,如果未能解决你的问题,请参考以下文章
Mongodb/Couchdb 代替 MySQL(从 PHP 切换到 Node)