php AES加密解密实现
php AES加密解密实现
AES 有三种算法,主要是对数据块的大小存在区别:
AES-128:需要提供 16 位的密钥 key
AES-192:需要提供 24 位的密钥 key
AES-256:需要提供 32 位的密钥 key
前奏
在PHP中使用AES加密和解密数据时,通常会使用openssl_encrypt和openssl_decrypt函数
安装和启用OpenSSL扩展
通过运行phpinfo()来检查OpenSSL扩展是否已启用
或者
php -m | grep openssl
生成密钥和初始化向量(IV)
AES加密需要一个密钥(Key)和一个初始化向量(IV)。密钥可以是任意长度的字符串,但推荐使用16、24或32字节的长度(对应AES-128, AES-192, AES-256)。初始化向量也应该是随机的,并且其长度应与密钥的块大小相匹配(对于AES,通常是16字节)
$key = openssl_random_pseudo_bytes(32); // AES-256, 32 bytes
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); // 16 bytes for AES-256-CBC
openssl_encrypt方法详解:
参数:
1.$data:加密明文
2.$method:加密方法: 可以通过openssl_get_cipher_methods()获取有效密码方式列表
3.$passwd:加密密钥[密码]
4.$options:数据格式选项(可选)【选项有:】:0,OPENSSL_RAW_DATA=1,OPENSSL_ZERO_PADDING=2,OPENSSL_NO_PADDING=3;它有着很重要的作用:
0:默认模式,自动进行 pkcs7 补位,同时自动进行 base64 编码
1:OPENSSL_RAW_DATA,自动进行 pkcs7 补位, 但是不自动进行 base64 编码
2:OPENSSL_ZERO_PADDING,需要自己进行 pkcs7 补位,同时自动进行 base64 编码
5.$iv:密初始化向量(可选),需要注意:如果method为DES−ECB,则iv无需填写
6.$tag:使用 AEAD 密码模式(GCM 或 CCM)时传引用的验证标签(可选)
7.$aad:附加的验证数据。(可选)
8.$tag_length:验证 tag 的长度。GCM 模式时,它的范围是 4 到 16(可选)
openssl_decrypt方法详解
参数:
1.$data:要解密的加密消息。
2.$method:解密方法:可以通过openssl_get_cipher_methods()获取有哪些解密方式
3.$passwd:解密密钥[密码]
4.$options:数据格式选项(可选)【选项有:】0,OPENSSL_RAW_DATA=1,OPENSSL_ZERO_PADDING=2,OPENSSL_NO_PADDING=3
5.$iv:密初始化向量(可选),需要注意:如果method为DES−ECB,则iv无需填写
6.$tag:AEAD密码模式下的身份验证标签(可选)
7.$aad:附加的验证数据。(可选)
php AES加密解密实现
下面示例还包含rsa,重点看AES就可以了
<?php
/*
* @Descripttion:
* @version: v1
* @Author: youhujun 2900976495@qq.com
* @Date: 2025-05-31 17:36:45
* @LastEditors: youhujun 2900976495@qq.com
* @LastEditTime: 2025-06-02 20:43:01
* @FilePath: \app\Service\Facade\Pub\V1\Util\Secret\SecretFacadeService.php
* Copyright (C) 2025 youhujun. All rights reserved.
*/
namespace App\Service\Facade\Pub\V1\Util\Secret;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
use App\Exceptions\Common\CommonException;
/**
* @see \App\Facade\Pub\V1\Util\Secret\SecretFacade
*/
class SecretFacadeService
{
public function test()
{
echo "SecretFacadeService test";
}
//AES 固定IV
private static $AES_IVRANDOM = "0123456789ABEDEF";
/**
* 加密方法
*/
private static $METHOD = 'AES-256-CBC';
/**
* 使用AES-128-CBC算法加密字符串
*
* @param string $security 待加密的字符串
* @param string $key 加密密钥
* @return string 返回Base64编码后的加密结果
*/
final public function encodeAES(String $security,String $key)
{
$encryptedText = openssl_encrypt(
$security,
self::$METHOD,
$key,
OPENSSL_RAW_DATA,
self::$AES_IVRANDOM
);
return base64_encode($encryptedText);
}
/**
* 使用AES-128-CBC算法解密字符串
*
* @param string $security 需要解密的Base64编码字符串
* @param string $key 解密密钥
* @return string|false 返回解密后的原始字符串,解密失败返回false
*/
final public function decodeAES(String $security,String $key)
{
$encrypted = base64_decode($security);
return openssl_decrypt(
$encrypted,
self::$METHOD,
$key,
OPENSSL_RAW_DATA,
self::$AES_IVRANDOM
);
}
/**
* 从Base64编码字符串获取公钥资源
* @param string $publicKeyString Base64编码的公钥
* @return resource|false 返回公钥资源,失败返回false
*/
public static function rsaGetPublicKey($publicKeyString) {
// Base64解码公钥字符串
$publicKeyDer = base64_decode($publicKeyString);
// 从DER格式转换为PEM格式(如果需要)
// 注意:PHP的openssl函数通常需要PEM格式的公钥
// 如果传入的是X509 DER格式,需要添加PEM头尾
$publicKeyPem = "-----BEGIN PUBLIC KEY-----\n" .
chunk_split(base64_encode($publicKeyDer), 64, "\n") .
"-----END PUBLIC KEY-----";
// 创建公钥资源
$publicKey = openssl_pkey_get_public($publicKeyPem);
//p($publicKey);die;
/**
* Resource id #628
*/
return $publicKey;
}
/**
* 公钥加密
* @param string $text 待加密的明文字符串
* @param string $publicKeyStr Base64编码的公钥
* @return string Base64编码的加密结果
* @throws RuntimeException 加密失败时抛出异常
*/
public function rsaEncrypt($text, $publicKeyStr)
{
try {
$publicKey = self::rsaGetPublicKey($publicKeyStr);
if ($publicKey === false)
{
throw new CommonException("PublicKeyError");
}
$data = $text;
$encryptedText = '';
// 使用公钥加密数据
$success = openssl_public_encrypt($data, $encryptedText, $publicKey, OPENSSL_PKCS1_PADDING);
if (!$success)
{
plog(['error'=>'EncryptError','errorInfo'=>openssl_error_string()],'EncryptError');
throw new CommonException('EncryptError');
}
// 释放公钥资源
openssl_free_key($publicKey);
// 将加密结果进行base64编码
return base64_encode($encryptedText);
} catch (Exception $e) {
plog(['error'=>'EncryptStringError','errorInfo'=>$e,'text'=>$text],'EncryptStringError');
throw new CommonException("EncryptStringError");
}
}
}