php没有加密解密标签,需用函数实现:aes-256-gcm认证加密、sodium密钥盒加密、password_hash密码哈希、hash_hmac签名验签,关键在函数选择、密钥管理与参数安全。

PHP本身没有“加密解密标签”这种语法结构——它不是HTML或模板引擎里的标记,而是通过函数调用来实现加密与解密。所谓“加标签”,其实是误将HTML的<tag></tag>概念套用到PHP逻辑上。真正起作用的是函数、参数、密钥管理和数据处理流程。
下面分四类常见场景,说明该怎么写代码才能安全、正确地加密和解密:
使用AES-256-GCM进行认证加密(推荐用于敏感数据存储/传输)
这是目前最推荐的对称加密方式,兼顾机密性与完整性:
- 生成32字节密钥和12字节IV,都必须随机且不可复用
- 加密时获取并保存GCM模式生成的
$tag,解密时必须传入 - 使用
OPENSSL_RAW_DATA标志,再用base64_encode()封装便于存储
$key = random_bytes(32); // 安全密钥,应存环境变量或KMS $iv = random_bytes(12); // GCM标准IV长度 $plaintext = "用户手机号:138****1234"; $encrypted = openssl_encrypt($plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag); $ciphertext = base64_encode($iv . $tag . $encrypted); // 拼接后统一编码 // 解密时分离:前12字节IV,接着16字节tag,剩余为密文 $data = base64_decode($ciphertext); $iv = substr($data, 0, 12); $tag = substr($data, 12, 16); $ciph = substr($data, 28); $decrypted = openssl_decrypt($ciph, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
使用sodium_crypto_secretbox进行现代密钥盒加密(PHP ≥ 7.2)
更简洁、抗侧信道攻击强,适合新项目:
- 密钥用
sodium_crypto_secretbox_keygen()生成 - nonce(类似IV)必须每次唯一,推荐24字节
- 函数返回完整密文,解密失败直接返回
false,不抛异常
$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(24);
$msg = "身份证号:11010119900307235X";
$encrypted = sodium_crypto_secretbox($msg, $nonce, $key);
$encoded = base64_encode($nonce . $encrypted);
// 解密
$raw = base64_decode($encoded);
$nonce = substr($raw, 0, 24);
$ciph = substr($raw, 24);
$plain = sodium_crypto_secretbox_open($ciph, $nonce, $key);
if ($plain === false) {
throw new Exception('密文被篡改或密钥/nonce错误');
}
存储密码请用password_hash()和password_verify()(不可逆哈希)
这不是“加密”,但常被混淆;它专为密码设计,自动加盐、选算法、防爆破:
- 不要尝试解密,只做比对
- 存数据库时直接存整个哈希字符串(含算法、成本、盐、密文)
- 验证时一行调用即可
$hash = password_hash("user123", PASSWORD_ARGON2ID, ['memory_cost' => 65536, 'time_cost' => 4]);
// 存入数据库字段,如:$pdo->prepare("INSERT INTO users(pwd) VALUES(?)")->execute([$hash]);
// 登录验证
if (password_verify($input_password, $stored_hash)) {
// 登录成功
}
签名验签用hash_hmac()保障数据完整性(如API请求校验)
不加密内容,但能确认来源和未被篡改:
- 私钥需保密,长度建议≥32字节
- 接收方用相同密钥重算HMAC,并用
hash_equals()比对(防时序攻击)
$key = random_bytes(32);
$data = json_encode(['uid'=>123, 'ts'=>time()]);
$signature = hash_hmac('sha256', $data, $key, true);
$encoded_sig = base64_encode($signature);
// 发送 $data 和 $encoded_sig
// 接收方:
if (!hash_equals(hash_hmac('sha256', $received_data, $key, true), base64_decode($received_sig))) {
die('签名无效');
}
不复杂但容易忽略细节。关键不在“加什么标签”,而在选对函数、管好密钥、处理好IV/nonce/tag、区分加密与哈希用途。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











