准备在 PHP 7.2 中移除 Mcrypt

Posted

技术标签:

【中文标题】准备在 PHP 7.2 中移除 Mcrypt【英文标题】:Preparing for removal of Mcrypt in PHP 7.2 【发布时间】:2017-07-30 12:22:39 【问题描述】:

所以随着时间的推移,mcrypt 将进入 php 7.2。 当然还有一个替代方案:openssl。

我发现使用 AES 256 CBC 并保留 IV 很难从 mcrypt 切换到 openssl。我对密码学有点陌生,所以我并不是真的什么都知道,但我了解基础知识。

假设我有以下代码

function encrypt($masterPassword, $data) 

    $keySize = mcrypt_get_key_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
    $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
    $key = mb_substr(hash('SHA256', $masterPassword), 0, $keySize);
    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CBC, $iv);
    return base64_encode($iv . $encrypted);


function decrypt($masterPassword, $base64) 

    $keySize = mcrypt_get_key_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
    $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
    $key = mb_substr(hash('SHA256', $masterPassword), 0, $keySize);
    $data = base64_decode($base64);
    $iv = substr($data, 0, $ivSize);
    $encrypted = substr($data, $ivSize, strlen($data));
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CBC, $iv);
    return trim($decrypted);

我如何“转换”此代码以使用 openssl insted of mcrypt?

【问题讨论】:

【参考方案1】:

您无法转换它,因为 Rijndael-256 不是 AES-256,而且 OpenSSL 扩展不附带 Rijndael-256 支持。 AES-256 是带有 256 位(32 字节)密钥的 Rijndael-128。

很遗憾,您必须重新加密所有数据。

编辑:另外,您当前使用的方案存在一些问题:

它缺乏身份验证(HMAC 是 PHP 中最简单的方法) 它缺少适当的填充(mcrypt 填充为零字节;您需要类似 PKCS#5 填充),这是块模式加密安全所必需的。 它不是字节安全的(您使用的是mb_substr()

好消息是 OpenSSL 会自动为您执行 PKCS#5 填充,但您应该更进一步,使用像 defuse/php-encryption 这样的可靠加密库。

【讨论】:

感谢您的小安全建议。我现在将我的 webapp 移植到 defuse/php-encryption 您可以通过对块大小进行空填充来使它们兼容。我一直将 mcrypt 迁移到 openssl,并且始终需要保留已加密的数据。 虽然不是可取的,但这适用于 mcrypt Rijndael-128 到 openssl AES,但不适用于 Rijndael-256。

以上是关于准备在 PHP 7.2 中移除 Mcrypt的主要内容,如果未能解决你的问题,请参考以下文章

Codeigniter 从浏览器 URL 中移除 index.php

PHP版DES算法加密数据

从 Joomla K2 中移除 RSS Feed 图标(链接)

在 KineticJS 中移除舞台

如何从 UITextField 中移除焦点?

android studio 中移除module和恢复module