php aes padding,php-使用AES / CBC / PKCS7Padding进行加密/解密

这篇博客介绍了如何在PHP中使用AES加密和解密,特别是采用CBC模式和PKCS7填充。文章通过示例展示了如何使用cryptography库以及自定义实现来执行加密和解密操作,包括设置密钥、加密和解密过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是使用流行的cryptography库执行此任务的方法.此代码改编自其文档.它使用问题中最初提供的数据,密钥和IV.

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

from cryptography.hazmat.primitives import padding

from cryptography.hazmat.backends import default_backend

from base64 import b64decode, b64encode

backend = default_backend()

padder = padding.PKCS7(128).padder()

unpadder = padding.PKCS7(128).unpadder()

data = b'demo'

data = padder.update(data) + padder.finalize()

key = b64decode('HJkPmTz+uY7wd0p1+w//DABgbvPq9/230RwEG2sJ9mo=')

iv = b64decode('AAAAAAAAAAAAAAAAAAAAAA==')

cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)

encryptor = cipher.encryptor()

ct = encryptor.update(data) + encryptor.finalize()

ct_out = b64encode(ct)

print(ct_out)

decryptor = cipher.decryptor()

plain = decryptor.update(ct) + decryptor.finalize()

plain = unpadder.update(plain) + unpadder.finalize()

print(plain)

产量

b'W2FEImF2qrAjaJ/LV+bgQA=='

b'demo'

只是为了好玩,这是一个不需要第三方软件包的实现.

通常,人们不会做这种事情,因为加密的第一个规则是“不要自行加密!”.但是,这是我作为Cryptopals挑战的一部分编写的一些AES代码. ;)通过ctypes直接调用标准OpenSSL库来进行AES ECB编码,然后使用它来执行CBC加密/解密.

该代码是在运行Python 3.6.0的Linux系统上开发和测试的,但也应该在Windows上运行.我认为它也可以在OSX上正常运行.

import os

from base64 import b64decode, b64encode

from ctypes import *

AES_MAXNR = 14

AES_BLOCK_SIZE = 16

DECODE = 0

ENCODE = 1

class AES_KEY(Structure):

_fields_ = [

("rd_key", c_long * 4 *(AES_MAXNR + 1)),

("rounds", c_int),

]

crypto = cdll.LoadLibrary("libeay32.dll" if os.name == "nt" else "libssl.so")

# Function prototypes

AES_set_encrypt_key = crypto.AES_set_encrypt_key

AES_set_encrypt_key.restype = c_int

# userKey, bits, key

AES_set_encrypt_key.argtypes = [c_char_p, c_int, POINTER(AES_KEY)]

AES_set_decrypt_key = crypto.AES_set_decrypt_key

AES_set_decrypt_key.restype = c_int

# userKey, bits, key

AES_set_decrypt_key.argtypes = [c_char_p, c_int, POINTER(AES_KEY)]

AES_ecb_encrypt = crypto.AES_ecb_encrypt

AES_ecb_encrypt.restype = None

#in, out, key, enc(1=encode, 0=decode)

AES_ecb_encrypt.argtypes = [c_char_p, c_char_p, POINTER(AES_KEY), c_int]

set_key = (AES_set_decrypt_key, AES_set_encrypt_key)

def set_aes_key(key, encode):

''' Create an AES encoding or decoding key '''

keylen = len(key)

valid = {16, 24, 32}

if keylen not in valid:

msg = f'Key length must be one of {valid}, not {keylen}'

raise ValueError(msg)

aes_key = AES_KEY()

rc = set_key[encode](c_char_p(key), keylen * 8, byref(aes_key))

if rc != 0:

# I don't think we can get here...

raise ValueError('Error generating AES key', rc)

return aes_key

def aes_ecb(block, aes_key, encode):

''' Encrypt or decrypt a single block '''

outbuff = create_string_buffer(AES_BLOCK_SIZE)

AES_ecb_encrypt(c_char_p(block), outbuff, byref(aes_key), encode)

return outbuff.raw

def PKCS7_pad(data):

padsize = AES_BLOCK_SIZE - len(data) % AES_BLOCK_SIZE

return data + bytes([padsize]) * padsize

def PKCS7_unpad(data):

offset = data[-1]

return data[:-offset]

def xor_bytes(a, b):

size = len(a)

a = int.from_bytes(a, 'big')

b = int.from_bytes(b, 'big')

return (a ^ b).to_bytes(size, 'big')

def aes_cbc_encode(data, key, iv):

ekey = set_aes_key(key, ENCODE)

data = PKCS7_pad(data)

cipher = []

for block in zip(*[iter(data)] * AES_BLOCK_SIZE):

block = bytes(block)

coded = aes_ecb(xor_bytes(iv, block), ekey, ENCODE)

cipher.append(coded)

iv = coded

return b''.join(cipher)

def aes_cbc_decode(data, key, iv):

dkey = set_aes_key(key, DECODE)

plain = []

for block in zip(*[iter(data)] * AES_BLOCK_SIZE):

block = bytes(block)

decoded = aes_ecb(block, dkey, DECODE)

plain.append(xor_bytes(iv, decoded))

iv = block

plain[-1] = PKCS7_unpad(plain[-1])

return b''.join(plain)

# Test

data = b'demo'

key = b64decode('HJkPmTz+uY7wd0p1+w//DABgbvPq9/230RwEG2sJ9mo=')

iv = b64decode('AAAAAAAAAAAAAAAAAAAAAA==')

cipher = aes_cbc_encode(data, key, iv)

out = b64encode(cipher)

print(out)

plain = aes_cbc_decode(cipher, key, iv)

print(plain)

产量

b'W2FEImF2qrAjaJ/LV+bgQA=='

b'demo'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值