python AES加密解密以及php解码

发布时间:2024-03-06 12:47:00

AES(Advanced Encryption Standard)是一种对称密钥加密算法,广泛应用于保护数据的安全性。AES算法使用相同的密钥来进行加密和解密操作,因此也被称为对称加密算法。以下是AES加密/解密的一般步骤:
在 Python 中,您可以使用 cryptography 库来进行 AES 加密和解密操作。如果您没有安装该库,可以通过以下命令安装:

pip install pycryptodomex

AES加密流程:

1. 选择密钥长度:AES算法支持128位、192位和256位三种密钥长度,根据安全需求选择合适的密钥长度。

2. 选择加密模式:AES算法支持多种加密模式,如ECB(电子密码本模式)、CBC(密码分组链接模式)、CTR(计数器模式)等。根据实际需求选择合适的加密模式。

3. 填充数据:由于AES算法要求明文长度必须是分组长度的整数倍,因此需要对最后一个分组进行填充操作,常用的填充方式有PKCS7填充和Zero Padding。

4. 进行加密:将填充后的明文通过AES算法和选择的加密模式与密钥进行加密,生成密文。

加密解密流程:

import base64

from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
from binascii import b2a_hex, a2b_hex

'''

pip install pycryptodomex
'''
key = 'sdf46asdfs54hgjg'
iv = '0102030405060708'

'''
因为密钥是16字节,所以明文加密时,字符串不足16字节的倍数,则要补充个数,例如:少4个,要补chr(4)chr(4)chr(4)chr(4),少2个,要补chr(2)chr(2)。chr(参数)中的参数是缺少的字节,要补全。
这里为什么要补充chr(缺少位的ASCII码作为参数)。是因为这样能更好的读取字符串最后字符时,知道有几个填充字符,从而能采用字符串切片操作而逆向清除填充字符,为自己理解这点,兴奋。
实现方法:明文字符串 + chr(16-len(明文字符串)%16) * (16 - len(明文字符串)%16) 
'''
def pad(data):
    text = data + chr(16 - len(data) % 16) * (16 - len(data) % 16)
    return text
#加密时字符串不足16字节倍数时,填充的字符是chr(缺少的字节数作为参数的),所以逆向清除填充的字符串,利用最后字符的ASCII码进行切片得出所需字符串。
def unpad(s):
    last_num = s[-1]
    text = s[:-last_num]
    return text

# ECB模式的加密函数,data为明文,key为16字节密钥
def aes_ECB_Encrypt(data, key):
    key = key.encode('utf-8')
    data = pad(data)  # 补位
    data = data.encode('utf-8')
    aes = AES.new(key=key, mode=AES.MODE_ECB)  # 创建加密对象

    # encrypt AES加密  B64encode为base64转二进制编码
    result = base64.b64encode(aes.encrypt(data))
    return str(result, 'utf-8')  # 以字符串的形式返回


def aes_ECB_Decrypt(data, key):  # ECB模式的解密函数,data为密文,key为16字节密钥
    key = key.encode('utf-8')
    aes = AES.new(key=key, mode=AES.MODE_ECB)  # 创建解密对象

    # decrypt AES解密  B64decode为base64 转码
    result = aes.decrypt(base64.b64decode(data))
    result = unpad(result)  # 除去补16字节的多余字符
    return str(result, 'utf-8')


def aes_CBC_Encrypt(data, key, iv):  # CBC模式的加密函数,data为明文,key为16字节密钥,iv为偏移量
    key = key.encode('utf-8')
    iv = iv.encode('utf-8')  # CBC 模式下的偏移量
    data = pad(data)  # 补位
    data = data.encode('utf-8')
    aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)  # 创建加密对象

    # encrypt AES加密  B64encode为base64转二进制编码
    result = base64.b64encode(aes.encrypt(data))
    return str(result, 'utf-8')


def aes_CBC_Decrypt(data, key, iv):  # CBC模式的解密函数,data为密文,key为16字节密钥
    key = key.encode('utf-8')
    iv = iv.encode('utf-8')
    aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)  # 创建解密对象

    # decrypt AES解密  B64decode为base64 转码
    result = aes.decrypt(base64.b64decode(data))
    result = unpad(result)  # 除去补16字节的多余字符
    return str(result, 'utf-8')



str_a = 'aaaaaa'

a = aes_ECB_Encrypt(str_a,key)
b = aes_ECB_Decrypt(a,key)
print(a)
print(b)


c = aes_CBC_Encrypt(str_a,key,iv)
c1 = aes_CBC_Decrypt(c,key,iv)
print(c)
print(c1)

php 解密

$data = 'ikehGMghr7ceT90H9CYydw==';
$key = 'sdf46asdfs54hgjg';
$iv  = '0102030405060708';
$cipherText = base64_decode($data);
$d = openssl_decrypt($cipherText, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
print_r($d);
exit();

$cipher_text = base64_decode('kC4vMEHWXAsk0ChAKpVp6w==');
$key = "sdf46asdfs54hgjg";

// 使用 openssl 进行解密
$decrypted = openssl_decrypt($cipher_text, 'AES-128-ECB', $key, OPENSSL_RAW_DATA);

// 打印解密后的内容
var_dump($decrypted);