如何将 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);
转换说明:
- 加密算法:
MCRYPT_RIJNDAEL_128
对应 OpenSSL 的AES-128-CBC
。 - 获取 IV 长度:
openssl_cipher_iv_length
函数返回指定加密算法所需的 IV 大小。 - 生成 IV:使用
openssl_random_pseudo_bytes
函数生成随机的 IV,以确保加密的安全性。 - 加密操作:
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);
解密过程说明:
- Base64 解码:通过
base64_decode
将编码后的密文还原为二进制数据。 - 提取 IV:使用
substr
提取出前$iv_size
个字节作为 IV。 - 提取密文:剩余部分就是加密后的密文。
- 解密操作:使用
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 的迁移,还使得我们的代码更加安全、符合现代加密技术的要求。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。