73 lines
2.3 KiB
PHP
73 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace common\services;
|
|
|
|
use Exception;
|
|
|
|
class DataEncryptor
|
|
{
|
|
/**
|
|
* @var string 加密方法
|
|
*/
|
|
private string $cipherMethod = 'AES-256-CBC'; // 加密方法
|
|
/**
|
|
* @var string 密钥
|
|
*/
|
|
private string $secretKey; // 密钥
|
|
/**
|
|
* @var false|int 初始化向量长度
|
|
*/
|
|
private $ivLength; // 初始化向量长度
|
|
|
|
/**
|
|
* 初始化加密类
|
|
* @param $key
|
|
*/
|
|
public function __construct($key) {
|
|
$this->secretKey = hash('sha256', $key, true); // 使用SHA-256哈希生成32字节的密钥
|
|
$this->ivLength = openssl_cipher_iv_length($this->cipherMethod);
|
|
}
|
|
|
|
/**
|
|
* 加密数据
|
|
* @param $data
|
|
* @return string
|
|
* @throws Exception
|
|
*/
|
|
public function encrypt($data): string
|
|
{
|
|
$iv = openssl_random_pseudo_bytes($this->ivLength);
|
|
$encryptedData = openssl_encrypt($data, $this->cipherMethod, $this->secretKey, OPENSSL_RAW_DATA, $iv);
|
|
if ($encryptedData === false) {
|
|
throw new Exception("加密失败" . openssl_error_string());
|
|
}
|
|
return 'xk_ase_256_'. base64_encode($iv . $encryptedData); // 将初始化向量和加密数据一起返回
|
|
}
|
|
|
|
/**
|
|
* 解密数据
|
|
* @param $base64EncodedEncryptedData
|
|
* @return string
|
|
* @throws Exception
|
|
*/
|
|
public function decrypt($base64EncodedEncryptedData): string
|
|
{
|
|
if (!is_string($base64EncodedEncryptedData)) return $base64EncodedEncryptedData;
|
|
// 替换xk_ase_256_
|
|
$base64EncodedEncryptedData = str_replace('xk_ase_256_', '', $base64EncodedEncryptedData);
|
|
$decodedData = base64_decode($base64EncodedEncryptedData);
|
|
if ($decodedData === false) {
|
|
throw new Exception("Base64 decoding failed");
|
|
}
|
|
$iv = substr($decodedData, 0, $this->ivLength);
|
|
$encryptedData = substr($decodedData, $this->ivLength);
|
|
$decryptedData = openssl_decrypt($encryptedData, $this->cipherMethod, $this->secretKey, OPENSSL_RAW_DATA, $iv);
|
|
if ($decryptedData === false) {
|
|
throw new Exception("解密失败" . openssl_error_string());
|
|
}
|
|
// $pattern = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\xFF]|[\x{E000}-\x{F8FF}]/u';
|
|
// if (!preg_match($pattern, $str)) return $str;
|
|
// ds($decryptedData);
|
|
return $decryptedData;
|
|
}
|
|
} |