在 PHP 7.1 升级过程中,很多项目会先撞上一个现实问题:原先依赖 mcrypt 的 AES 加解密代码还能不能继续用。答案很明确,mcrypt 早已被官方判定为过时扩展,PHP 7.2 起更是从核心中移除并转到 PECL,因此在维护旧项目或升级运行环境时,改用 OpenSSL 已经不是“优化项”,而是更稳妥的兼容方案。本文就以一个可直接替换的 PHP 示例为主线,说明 `mcrypt_module_open()` 迁移到 OpenSSL 后该怎么写,以及读者该如何判断这份代码是否适合自己的现有业务。
为什么要从 mcrypt 迁移到 OpenSSL
这次调整的背景并不复杂。mcrypt 扩展已经过时了大约 10 年,而且接口本身使用起来也不算简洁,因此官方逐步停止推荐,并明确由 OpenSSL 取代其常见用途。
对 PHP 开发者来说,这意味着两个直接影响:
- 在 PHP 7.1 及之后的升级过程中,继续沿用旧的 mcrypt 写法会增加兼容风险。
- 从 PHP 7.2 起,mcrypt 不再属于核心代码的一部分,而是移到 PECL 中,部署和维护成本会更高。
也正因为如此,PHP 手册在 7.1 的迁移说明中,给出的替代方向就是使用 OpenSSL。对于原本只是在做常规 AES 加解密的业务代码,迁移的重点通常不在“重写整套逻辑”,而是换掉底层调用方式,同时保留原有输入、密钥和返回结果的使用习惯。
PHP 7.1 可用的 AES 加解密替代实现
下面这段代码就是一个直接可用的替代方案,核心思路是用 `openssl_encrypt()` 和 `openssl_decrypt()` 代替原来的 mcrypt 相关函数,并通过 Base64 处理加密结果,方便存储和传输。
/**
* [AesSecurity aes加密,支持PHP7.1]
*/
class AesSecurity
{
/**
* [encrypt aes加密]
* @param [type] $input [要加密的数据]
* @param [type] $key [加密key]
* @return [type] [加密后的数据]
*/
public static function encrypt($input, $key)
{
$data = openssl_encrypt($input, 'AES-128-ECB', $key, OPENSSL_RAW_DATA);
$data = base64_encode($data);
return $data;
}
/**
* [decrypt aes解密]
* @param [type] $sStr [要解密的数据]
* @param [type] $sKey [加密key]
* @return [type] [解密后的数据]
*/
public static function decrypt($sStr, $sKey)
{
$decrypted = openssl_decrypt(base64_decode($sStr), 'AES-128-ECB', $sKey, OPENSSL_RAW_DATA);
return $decrypted;
}
}
这份实现保留了一个很清晰的调用结构:
- `encrypt($input, $key)` 用来接收原始数据和密钥,返回加密后的字符串。
- `decrypt($sStr, $sKey)` 用来接收密文和密钥,返回解密后的原文。
其中有几个关键点值得单独看清:
加密流程做了什么
加密时,代码调用的是:
openssl_encrypt($input, 'AES-128-ECB', $key, OPENSSL_RAW_DATA);
这里指定的算法是 `AES-128-ECB`,也就是使用 AES-128,工作模式为 ECB。第四个参数使用 `OPENSSL_RAW_DATA`,表示先拿到原始二进制结果,而不是让 OpenSSL 直接返回编码后的文本。
随后再通过:
$data = base64_encode($data);
把二进制密文转成 Base64 字符串。这样做的好处是更方便在接口、数据库或表单字段中传递,不容易因为二进制内容导致编码问题。
解密流程如何对应回来
解密逻辑与加密逻辑是成对出现的。因为加密结果被做过 Base64 编码,所以解密前需要先还原:
base64_decode($sStr)
之后再交给 `openssl_decrypt()`:
openssl_decrypt(base64_decode($sStr), 'AES-128-ECB', $sKey, OPENSSL_RAW_DATA);
只要算法、密钥和数据处理方式与加密阶段保持一致,就可以把原文还原出来。这也是迁移旧代码时最需要核对的部分:不是简单把函数名替换掉就结束,而是要确保加密模式、密钥长度预期以及编码过程都能前后对应。
这段替代代码适合什么场景
如果你的旧项目原本就是基于 mcrypt 做一段相对简单的 AES 对称加解密,并且业务上已经约定好输入输出格式,那么这类写法通常很适合作为 PHP 7.1 环境下的替代实现。
它的优点主要有三点:
- 接口简单,容易直接封装成工具类替换旧代码。
- 依赖的是 OpenSSL,符合 PHP 官方迁移方向。
- 加密和解密逻辑对称,便于排查线上兼容问题。
不过,是否能“无缝替换”,仍然取决于旧系统此前的具体实现。例如:
- 旧代码使用的是否也是 AES-128。
- 旧代码的工作模式是否同样为 ECB。
- 历史密文是否经过 Base64 编码保存。
- 调用方对返回值格式是否有固定依赖。
如果这些条件一致,迁移成本通常较低;如果历史实现里还混入了初始化向量、不同填充方式,或者跨语言系统之间已经固定了协议格式,就需要按现有协议逐项比对,而不是直接照搬。
迁移旧项目时的几个注意点
虽然原始示例已经足够简洁,但真正用于项目替换时,仍建议先把几个边界条件确认清楚。
先确认历史算法参数
示例中写死的是 `AES-128-ECB`。如果旧系统用的不是这个组合,而是其他 AES 规格或模式,那么即便代码能运行,也可能解不出历史数据。因此第一步不是直接替换,而是先确认老数据到底按什么规则生成。
再确认密文存储格式
这份代码把 OpenSSL 返回的原始二进制数据再做了一次 Base64 编码,这会直接影响数据库字段内容、接口返回值以及跨系统传输格式。只要上下游原本预期的是字符串,这样处理通常更省事;但如果历史系统保存的是十六进制串或其他编码形式,就要额外适配。
升级时顺手检查运行环境
文章讨论的核心背景就是 PHP 7.1 和 PHP 7.2 的迁移问题。实际落地时,除了替换 `mcrypt_module_open()` 相关逻辑,也应确认目标环境已具备 OpenSSL 扩展支持,否则代码层面改完,部署阶段仍然会卡住。
结语
对于 PHP 7.1 之后的项目来说,用 OpenSSL 替代 mcrypt 已经是主流且现实的方案。上面的 `AesSecurity` 示例提供了一种足够直接的 AES 加解密封装方式:保留简单调用接口,用 `openssl_encrypt()` 和 `openssl_decrypt()` 完成核心逻辑,再通过 Base64 处理输出结果。
如果你的旧业务本身就是类似的 AES 对称加密需求,这段代码基本可以作为迁移起点,再根据实际项目中的算法模式、密钥规则和历史数据格式自行改编即可。











