PHP 和 Python 实现 AES/CBC/PKCS7 加密解密(支持 Base64 和 Hex 编码)

1. Python 版本

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

class AESUtilCBC:
    def __init__(self, key, iv):
        self.key = key.encode('utf-8')
        self.iv = iv.encode('utf-8')
        self.pad_length = AES.block_size

    def encrypt(self, data):
        try:
            data = data.encode('utf-8')
            cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
            padded_data = pad(data, self.pad_length, style='pkcs7')
            encrypted_data = cipher.encrypt(padded_data)
            encoded_data = base64.b64encode(encrypted_data).decode('utf-8')
            return encoded_data
        except Exception as e:
            raise Exception(f"Encryption failed: {str(e)}")

    def decrypt(self, encrypted_data):
        try:
            encrypted_bytes = base64.b64decode(encrypted_data)
            cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
            decrypted_data = cipher.decrypt(encrypted_bytes)
            unpadded_data = unpad(decrypted_data, self.pad_length, style='pkcs7')
            return unpadded_data.decode('utf-8')
        except Exception as e:
            raise Exception(f"Decryption failed: {str(e)}")

# 示例使用 AESUtilCBC 类进行加密和解密
key = 'Nhic0EAJqsIdMBfs'  # 16字节的密钥
iv = 'Nhic0EAJqsIdMBfs'   # 16字节的 IV

aes_util = AESUtilCBC(key, iv)
data = '123456'

encrypted_data = aes_util.encrypt(data)
print(f"加密后的数据: {encrypted_data}")

decrypted_data = aes_util.decrypt(encrypted_data)
print(f"解密后的数据: {decrypted_data}")

运行结果:

加密后的数据: Qun8LbhlewyVvRQDzrNCIQ==
解密后的数据: 123456

2. PHP 版本

<?php

class AESUtilCBC
{
    private $key = 'Nhic0EAJqsIdMBfs';
    private $iv = 'Nhic0EAJqsIdMBfs';
    private $algo = 'AES-128-CBC';
    private $options = OPENSSL_RAW_DATA;

    public function __construct($key = null, $iv = null, $algo = null, $options = null)
    {
        if ($key) $this->key = $key;
        if ($iv) $this->iv = $iv;
        if ($algo) $this->algo = $algo;
        if ($options) $this->options = $options;
    }

    public function encrypt($data)
    {
        try {
            $encryptedData = openssl_encrypt($data, $this->algo, $this->key, $this->options, $this->iv);
            return base64_encode($encryptedData);
        } catch (Exception $e) {
            return false;
        }
    }

    public function decrypt($encryptedData)
    {
        try {
            $decodedData = base64_decode($encryptedData);
            return openssl_decrypt($decodedData, $this->algo, $this->key, $this->options, $this->iv);
        } catch (Exception $e) {
            return false;
        }
    }

    public function encryptHexData($hexData)
    {
        try {
            $encrypted = openssl_encrypt($hexData, $this->algo, $this->key, OPENSSL_RAW_DATA, $this->iv);
            return bin2hex($encrypted);
        } catch (Exception $e) {
            return false;
        }
    }

    public function decryptHexData($hexData)
    {
        try {
            $hexData = pack("H*", $hexData);
            return openssl_decrypt($hexData, $this->algo, $this->key, OPENSSL_RAW_DATA, $this->iv);
        } catch (Exception $e) {
            return false;
        }
    }
}

$util = new AESUtilCBC();

$encrypted = $util->encrypt('123456');
print("\u52A0\u5BC6\u540E\u7684\u6570\u636E: {$encrypted}<br>");

$decrypted = $util->decrypt($encrypted);
print("\u89E3\u5BC6\u540E\u7684\u6570\u636E: {$decrypted}<br>");

$hexEncrypted = $util->encryptHexData('123456');
print("hex\u52A0\u5BC6\u540E\u7684\u6570\u636E: {$hexEncrypted}<br>");

$hexDecrypted = $util->decryptHexData($hexEncrypted);
print("hex\u89E3\u5BC6\u540E\u7684\u6570\u636E: {$hexDecrypted}");

运行结果:

加密后的数据: Qun8LbhlewyVvRQDzrNCIQ==
解密后的数据: 123456
hex加密后的数据: 42e9fc2db8657b0c95bd1403ceb34221
hex解密后的数据: 123456

3. 其他

1. 在线测试

可以通过下面的网站测试加密结果是否一致:

  • https://www.ssleye.com/ssltool/aes_cipher.html

在线加密测试图

2. 修改加密长度

  • PHP 中可通过 $algo 设置 AES-128-CBC 或 AES-256-CBC
  • Python 根据 key 长度决定,16 字节是 128-bit,32 字节是 256-bit

3. IV 长度

  • IV 必须是 16 字节
  • key 和 iv 允许一致

4. 加密不一致问题

  • key 长度不足 16/32 时,在 PHP/
    Python 里需要补全,且补全方式不同也会导致结果不一致

5. PHP 修改模式

  • CBC 模式可以改为 ECB:如 AES-128-ECB

6. PHP Hex 解密说明

  • 加密: bin2hex
  • 解密: pack("H*", $hexData) 将 16 进制字符串 转为二进制
  • 在在线测试时,选择 “hex” 编码方式即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值