PHP 加解密服务类

wen PHP项目 3

我将为您创建一个PHP加解密服务类,支持多种加密方式和场景:

PHP 加解密服务类

<?php
/**
 * 加解密服务类
 * 支持AES、DES、RSA等常见加密算法
 */
class CryptoService
{
    private $aesKey;
    private $aesIv;
    private $rsaPrivateKey;
    private $rsaPublicKey;
    /**
     * 构造函数
     */
    public function __construct(array $config = [])
    {
        $this->aesKey = $config['aes_key'] ?? 'default_aes_key_32bytes_long_123456';
        $this->aesIv = $config['aes_iv'] ?? '1234567812345678';
        $this->rsaPrivateKey = $config['rsa_private_key'] ?? null;
        $this->rsaPublicKey = $config['rsa_public_key'] ?? null;
    }
    /**
     * ==================== AES 加解密 ====================
     */
    /**
     * AES-256-CBC 加密
     * @param string $data 待加密数据
     * @param string $key 密钥(32字节)
     * @param string $iv 初始化向量(16字节)
     * @return string Base64编码的密文
     */
    public function aesEncrypt($data, $key = null, $iv = null)
    {
        $key = $key ?? $this->aesKey;
        $iv = $iv ?? $this->aesIv;
        // 确保密钥长度正确
        $key = substr(hash('sha256', $key, true), 0, 32);
        $iv = substr($iv, 0, 16);
        $encrypted = openssl_encrypt(
            $data,
            'AES-256-CBC',
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
        if ($encrypted === false) {
            throw new Exception('AES加密失败: ' . openssl_error_string());
        }
        return base64_encode($encrypted);
    }
    /**
     * AES-256-CBC 解密
     */
    public function aesDecrypt($encryptedData, $key = null, $iv = null)
    {
        $key = $key ?? $this->aesKey;
        $iv = $iv ?? $this->aesIv;
        $key = substr(hash('sha256', $key, true), 0, 32);
        $iv = substr($iv, 0, 16);
        $decrypted = openssl_decrypt(
            base64_decode($encryptedData),
            'AES-256-CBC',
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
        if ($decrypted === false) {
            throw new Exception('AES解密失败: ' . openssl_error_string());
        }
        return $decrypted;
    }
    /**
     * AES-GCM 加密(认证加密)
     */
    public function aesGcmEncrypt($data, $key = null, $aad = '')
    {
        $key = $key ?? $this->aesKey;
        $key = substr(hash('sha256', $key, true), 0, 32);
        $iv = random_bytes(12); // GCM推荐12字节IV
        $tag = '';
        $encrypted = openssl_encrypt(
            $data,
            'aes-256-gcm',
            $key,
            OPENSSL_RAW_DATA,
            $iv,
            $tag,
            $aad,
            16
        );
        if ($encrypted === false) {
            throw new Exception('AES-GCM加密失败');
        }
        // 返回 iv + tag + 密文
        return base64_encode($iv . $tag . $encrypted);
    }
    /**
     * AES-GCM 解密
     */
    public function aesGcmDecrypt($encryptedData, $key = null, $aad = '')
    {
        $key = $key ?? $this->aesKey;
        $key = substr(hash('sha256', $key, true), 0, 32);
        $data = base64_decode($encryptedData);
        $iv = substr($data, 0, 12);
        $tag = substr($data, 12, 16);
        $ciphertext = substr($data, 28);
        $decrypted = openssl_decrypt(
            $ciphertext,
            'aes-256-gcm',
            $key,
            OPENSSL_RAW_DATA,
            $iv,
            $tag,
            $aad
        );
        if ($decrypted === false) {
            throw new Exception('AES-GCM解密失败');
        }
        return $decrypted;
    }
    /**
     * ==================== RSA 加解密 ====================
     */
    /**
     * RSA 公钥加密
     */
    public function rsaEncrypt($data, $publicKey = null)
    {
        $publicKey = $publicKey ?? $this->rsaPublicKey;
        if (!$publicKey) {
            throw new Exception('缺少RSA公钥');
        }
        $publicKeyResource = openssl_pkey_get_public($publicKey);
        if (!$publicKeyResource) {
            throw new Exception('无效的RSA公钥');
        }
        $encrypted = '';
        // 分段加密(RSA最大加密长度为密钥长度/8 - 11)
        $keyLength = openssl_pkey_get_details($publicKeyResource)['bits'] / 8;
        $maxLength = $keyLength - 11;
        $dataLength = strlen($data);
        for ($i = 0; $i < $dataLength; $i += $maxLength) {
            $chunk = substr($data, $i, $maxLength);
            $encryptedChunk = '';
            if (!openssl_public_encrypt($chunk, $encryptedChunk, $publicKeyResource)) {
                throw new Exception('RSA加密失败');
            }
            $encrypted .= $encryptedChunk;
        }
        return base64_encode($encrypted);
    }
    /**
     * RSA 私钥解密
     */
    public function rsaDecrypt($encryptedData, $privateKey = null)
    {
        $privateKey = $privateKey ?? $this->rsaPrivateKey;
        if (!$privateKey) {
            throw new Exception('缺少RSA私钥');
        }
        $privateKeyResource = openssl_pkey_get_private($privateKey);
        if (!$privateKeyResource) {
            throw new Exception('无效的RSA私钥');
        }
        $data = base64_decode($encryptedData);
        $keyLength = openssl_pkey_get_details($privateKeyResource)['bits'] / 8;
        $decrypted = '';
        $dataLength = strlen($data);
        for ($i = 0; $i < $dataLength; $i += $keyLength) {
            $chunk = substr($data, $i, $keyLength);
            $decryptedChunk = '';
            if (!openssl_private_decrypt($chunk, $decryptedChunk, $privateKeyResource)) {
                throw new Exception('RSA解密失败');
            }
            $decrypted .= $decryptedChunk;
        }
        return $decrypted;
    }
    /**
     * ==================== 其他加密方法 ====================
     */
    /**
     * 生成密码哈希
     */
    public function hashPassword($password)
    {
        return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
    }
    /**
     * 验证密码
     */
    public function verifyPassword($password, $hash)
    {
        return password_verify($password, $hash);
    }
    /**
     * HMAC-SHA256签名
     */
    public function hmacSign($data, $key = null)
    {
        $key = $key ?? $this->aesKey;
        return base64_encode(hash_hmac('sha256', $data, $key, true));
    }
    /**
     * HMAC验证
     */
    public function hmacVerify($data, $signature, $key = null)
    {
        $expected = $this->hmacSign($data, $key);
        return hash_equals($expected, $signature);
    }
    /**
     * 生成加密的唯一ID
     */
    public function generateEncryptedId($id)
    {
        return $this->aesEncrypt((string)$id);
    }
    /**
     * 解密ID
     */
    public function decryptId($encryptedId)
    {
        return (int)$this->aesDecrypt($encryptedId);
    }
    /**
     * ==================== 工具方法 ====================
     */
    /**
     * 生成随机密钥
     */
    public static function generateRandomKey($length = 32)
    {
        return bin2hex(random_bytes($length / 2));
    }
    /**
     * 生成RSA密钥对
     */
    public static function generateRsaKeyPair($bits = 2048)
    {
        $config = [
            'private_key_bits' => $bits,
            'private_key_type' => OPENSSL_KEYTYPE_RSA,
        ];
        $resource = openssl_pkey_new($config);
        openssl_pkey_export($resource, $privateKey);
        $publicKey = openssl_pkey_get_details($resource);
        return [
            'private_key' => $privateKey,
            'public_key' => $publicKey['key']
        ];
    }
    /**
     * URL安全的base64编码
     */
    public function base64UrlEncode($data)
    {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }
    /**
     * URL安全的base64解码
     */
    public function base64UrlDecode($data)
    {
        return base64_decode(strtr($data, '-_', '+/'));
    }
    /**
     * 数据签名(包含时间戳防重放)
     */
    public function signWithTimestamp($data)
    {
        $timestamp = time();
        $signData = $timestamp . ':' . $data;
        $signature = $this->hmacSign($signData);
        return [
            'data' => $data,
            'timestamp' => $timestamp,
            'signature' => $signature
        ];
    }
    /**
     * 验证带时间戳的签名
     */
    public function verifyTimestampSign($data, $timestamp, $signature, $timeWindow = 300)
    {
        // 检查时间戳是否在有效窗口内
        if (abs(time() - $timestamp) > $timeWindow) {
            return false;
        }
        return $this->hmacVerify($timestamp . ':' . $data, $signature);
    }
}

使用示例:

<?php
// 加载类
require_once 'CryptoService.php';
// 初始化服务
$cryptoService = new CryptoService([
    'aes_key' => 'your-32-character-secret-key',
    'aes_iv' => '16-character-iv',
    'rsa_private_key' => file_get_contents('private.pem'),
    'rsa_public_key' => file_get_contents('public.pem')
]);
// AES加密示例
try {
    $data = '需要加密的敏感数据';
    // AES-CBC加密
    $encrypted = $cryptoService->aesEncrypt($data);
    echo "AES加密结果: " . $encrypted . "\n";
    echo "AES解密结果: " . $cryptoService->aesDecrypt($encrypted) . "\n";
    // AES-GCM加密(更安全)
    $encryptedGcm = $cryptoService->aesGcmEncrypt($data);
    echo "AES-GCM加密: " . $encryptedGcm . "\n";
    echo "AES-GCM解密: " . $cryptoService->aesGcmDecrypt($encryptedGcm) . "\n";
    // RSA加密
    $rsaEncrypted = $cryptoService->rsaEncrypt($data);
    echo "RSA加密: " . $rsaEncrypted . "\n";
    echo "RSA解密: " . $cryptoService->rsaDecrypt($rsaEncrypted) . "\n";
    // 密码哈希
    $passwordHash = $cryptoService->hashPassword('user_password');
    echo "密码验证: " . var_export($cryptoService->verifyPassword('user_password', $passwordHash), true) . "\n";
    // HMAC签名
    $signature = $cryptoService->hmacSign('要签名的数据');
    echo "HMAC验证: " . var_export($cryptoService->hmacVerify('要签名的数据', $signature), true) . "\n";
} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

主要特性:

  1. AES对称加密:支持CBC和GCM模式,GCM模式提供认证加密
  2. RSA非对称加密:支持公钥加密、私钥解密
  3. 密码安全:使用bcrypt算法进行密码哈希
  4. 数据完整性:提供HMAC签名验证
  5. 安全工具:时间戳防重放、URL安全编码等

这个服务类适合在PHP项目中使用,可以根据实际需求进行扩展或修改。

抱歉,评论功能暂时关闭!