头图

如何将 mcrypt_encrypt 转换为 openssl_encrypt:详细教程

随着 PHP 7.1 版本的发布,mcrypt_encrypt 函数已被标记为废弃,并在 PHP 7.2 中完全移除。由于其安全性问题,开发者需要找到替代方案。openssl_encrypt 是 OpenSSL 库的一部分,提供了更安全、更强大的加密功能,成为了 PHP 开发中处理加密的推荐选择。

在本教程中,我们将详细解释如何将原本使用 mcrypt_encrypt 进行的加密操作转换为使用 openssl_encrypt,并结合代码示例和注释,确保你能够理解每一步的含义和作用。


1. mcrypt_encrypt 示例代码

$key = 'mysecurekey';
$plaintext = 'Hello, World!';
$cipher = MCRYPT_RIJNDAEL_128;

$iv_size = mcrypt_get_iv_size($cipher, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$ciphertext = mcrypt_encrypt($cipher, $key, $plaintext, MCRYPT_MODE_CBC, $iv);

代码分析:

  • $key 是加密所用的密钥。
  • $plaintext 是需要加密的明文。
  • $cipher 选择了 MCRYPT_RIJNDAEL_128(即 AES-128)作为加密算法。
  • $iv_size 计算出初始化向量(IV)的大小。
  • $iv 是通过 mcrypt_create_iv 生成的随机 IV,用于确保加密安全性。
  • $ciphertext 是最终生成的密文。

2. 使用 openssl_encrypt 替代 mcrypt_encrypt

由于 mcrypt_encrypt 已经被废弃,我们需要将其替换为 openssl_encrypt,以下是转换后的代码示例:

$key = 'mysecurekey';
$plaintext = 'Hello, World!';
$cipher = 'AES-128-CBC';  // 对应 MCRYPT_RIJNDAEL_128

$iv_size = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($iv_size);

$ciphertext = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);

转换说明:

  1. 加密算法MCRYPT_RIJNDAEL_128 对应 OpenSSL 的 AES-128-CBC
  2. 获取 IV 长度openssl_cipher_iv_length 函数返回指定加密算法所需的 IV 大小。
  3. 生成 IV:使用 openssl_random_pseudo_bytes 函数生成随机的 IV,以确保加密的安全性。
  4. 加密操作openssl_encrypt 用于加密明文,生成加密后的密文。

3. 处理密钥长度问题

AES 加密算法对密钥长度有严格要求:

  • AES-128 需要 16 字节长的密钥。
  • AES-192 需要 24 字节长的密钥。
  • AES-256 需要 32 字节长的密钥。

如果你的密钥长度不符合要求,你可以通过哈希函数来生成符合要求的密钥。例如,使用 SHA256 哈希函数生成一个 32 字节的密钥:

$key = 'mysecurekey';
$key = hash('sha256', $key, true);

在这个示例中,hash('sha256', $key, true) 将输入的密钥 mysecurekey 通过 SHA256 算法生成了一个长度为 32 字节的密钥,确保与 AES 的要求相匹配。


4. 加密数据的传输和存储

通常情况下,加密后的数据并不适合直接进行传输或存储,因为它可能包含二进制数据。为了便于传输或存储,我们可以使用 Base64 编码将加密后的数据转换为可打印的字符串格式。

$ciphertext = base64_encode($iv . $ciphertext);

操作解释:

  • Base64 编码:将 IV 和密文拼接在一起,然后使用 base64_encode 函数对拼接结果进行编码,得到一个可打印的字符串。这样可以方便地传输和存储加密后的数据。

5. 解密过程

使用 openssl_decrypt 来解密 Base64 编码的密文,首先需要解码密文,然后提取出初始化向量(IV)和加密的真实数据。下面是解密过程的完整示例:

$ciphertext = base64_decode($ciphertext);  // 解码 base64 格式的密文
$iv = substr($ciphertext, 0, $iv_size);  // 提取 IV
$ciphertext = substr($ciphertext, $iv_size);  // 提取密文

$plaintext = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv);

解密过程说明:

  1. Base64 解码:通过 base64_decode 将编码后的密文还原为二进制数据。
  2. 提取 IV:使用 substr 提取出前 $iv_size 个字节作为 IV。
  3. 提取密文:剩余部分就是加密后的密文。
  4. 解密操作:使用 openssl_decrypt 函数解密密文,恢复原始的明文。

6. 示例工作流程脑图

+-------------------------------+
|        加密与解密流程           |
+-------------------------------+
|  1. 设置密钥与明文              |
|  2. 生成加密所需的IV            |
|  3. 使用 openssl_encrypt 加密   |
|  4. base64编码以便传输与存储    |
|  5. 传输或存储加密数据          |
|  6. 接收后解码base64            |
|  7. 使用 openssl_decrypt 解密   |
+-------------------------------+

7. 总结

在将 mcrypt_encrypt 转换为 openssl_encrypt 的过程中,我们需要注意以下几个关键点:

  • 加密算法的选择MCRYPT_RIJNDAEL_128 在 OpenSSL 中对应 AES-128-CBC
  • 密钥长度的处理:AES 对密钥长度有严格要求,可以使用哈希函数生成符合要求的密钥。
  • IV 的生成与管理:IV 的生成需要随机化,使用 openssl_random_pseudo_bytes 函数,并确保在加密和解密时一致。
  • 数据的编码与传输:加密后的数据使用 Base64 编码,以便于传输和存储。
  • 解密过程:与加密过程相反,解密时需要先解码 Base64,然后再使用相同的算法和密钥解密数据。

通过此步骤的转换,我们不仅实现了从 mcrypt 到 openssl 的迁移,还使得我们的代码更加安全、符合现代加密技术的要求。


蓝易云
28 声望3 粉丝