5 回答

TA貢獻1812條經驗 獲得超5個贊
這是完整的代碼,以防有人仍在尋找。
測試針對:
python3.6
python3.8
** 使用pycryptodome
encrypt_aes.py
import hashlib
from Crypto.Cipher import AES
import base64
class AES_pkcs5:
def __init__(self,key:str, mode:AES.MODE_ECB=AES.MODE_ECB,block_size:int=16):
self.key = self.setKey(key)
self.mode = mode
self.block_size = block_size
def pad(self,byte_array:bytearray):
"""
pkcs5 padding
"""
pad_len = self.block_size - len(byte_array) % self.block_size
return byte_array + (bytes([pad_len]) * pad_len)
# pkcs5 - unpadding
def unpad(self,byte_array:bytearray):
return byte_array[:-ord(byte_array[-1:])]
def setKey(self,key:str):
# convert to bytes
key = key.encode('utf-8')
# get the sha1 method - for hashing
sha1 = hashlib.sha1
# and use digest and take the last 16 bytes
key = sha1(key).digest()[:16]
# now zero pad - just incase
key = key.zfill(16)
return key
def encrypt(self,message:str)->str:
# convert to bytes
byte_array = message.encode("UTF-8")
# pad the message - with pkcs5 style
padded = self.pad(byte_array)
# new instance of AES with encoded key
cipher = AES.new(self.key, AES.MODE_ECB)
# now encrypt the padded bytes
encrypted = cipher.encrypt(padded)
# base64 encode and convert back to string
return base64.b64encode(encrypted).decode('utf-8')
def decrypt(self,message:str)->str:
# convert the message to bytes
byte_array = message.encode("utf-8")
# base64 decode
message = base64.b64decode(byte_array)
# AES instance with the - setKey()
cipher= AES.new(self.key, AES.MODE_ECB)
# decrypt and decode
decrypted = cipher.decrypt(message).decode('utf-8')
# unpad - with pkcs5 style and return
return self.unpad(decrypted)
if __name__ == '__main__':
# message to encrypt
message = 'hello world'
secret_key = "65715AC165715AC165715AC165715AC1"
AES_pkcs5_obj = AES_pkcs5(secret_key)
encrypted_message = AES_pkcs5_obj.encrypt(message)
print(encrypted_message)
decrypted_message = AES_pkcs5_obj.decrypt(encrypted_message)
print(decrypted_message)
輸出:
>>> python encrypt_aes.py
>>> PDhIFEVqLrJiZQC90FPHiQ== # encrypted message
>>> hello world # and the decrypted one
我已經測試了許多已經可用的代碼,但沒有一個提供像 java 那樣的精確加密。所以,這是所有找到的博客和早期編寫的與 python2 兼容的代碼的組合

TA貢獻1859條經驗 獲得超6個贊
我已經用下面的代碼構建了 PKCS5 填充,并且按預期工作。
block_size=16
pad = lambda s: s + (block_size - len(s) % block_size) * chr(block_size - len(s) % block_size)
加密方法重寫如下:
def encrypt(plainText,key):
aes = AES.new(key, AES.MODE_ECB)
encrypt_aes = aes.encrypt(pad(plainText))
encrypted_text = str(base64.encodebytes (encrypt_aes), encoding = 'utf-8')
return encrypted_text

TA貢獻1796條經驗 獲得超4個贊
PKCS 5(或7)填充不是添加0個字節,而是添加一個c
字節with value
c (where
1 <= c <= 16 ) if you're
c`字節,短于塊長度倍數。
因此,如果您已經有 16 的倍數,請添加完整的 16 個字節的值 16,并且如果您的最后一個塊是“停止”(4 個字節),我們將添加 12 個字節的值(十六進制的 12)來填充該塊0xc
。ETC。
這樣,接收者(在解密最終塊之后)可以檢查最后一個字節c
并檢查該值是否為1 <= c <= 16
(如果不是,則拒絕解密),然后檢查最后一個c
字節確實都是相同的值,然后將它們從解密。這樣,接收方不必猜測最后一個塊的多少字節只是填充或實際上是純文本的一部分。以 PKCS 方式執行此操作是明確的。
我將把編碼留給你。

TA貢獻1831條經驗 獲得超10個贊
您可以使用aes-pkcs5
包。我是作者,它使用cryptography
包而不是pycrypto
其他答案中使用的過時的包,并且與 Python 3.7+ 兼容。
您可以通過 pip 安裝:
pip install aes-pkcs5
您使用以下方式發布的相同代碼aes-pkcs5
:
from aes_pkcs5.algorithms.aes_ecb_pkcs5_padding import AESECBPKCS5Padding
key = "92oifgGh893*cj%7"
cipher = AESECBPKCS5Padding(key, "b64")
text = '{ "Message": "hello this is a plain text" , "user":"john.doe", "Email":"[email protected]}'
encrypted_text = cipher.encrypt(text)

TA貢獻1851條經驗 獲得超4個贊
有時,您可以使用由空字節分隔的隨機字符串進行填充,以添加一點隨機性。
import random
import string
from Crypto.Cipher import AES
NULL_BYTE = '\x00'
def random_string(size: int) -> str:
return ''.join([
random.choice(string.printable) for _ in range(size)
])
def encode_aes(value: str, key: str) -> bytes:
cipher = AES.new(key[:32], AES.MODE_ECB)
mod = len(value) % cipher.block_size
padding = (cipher.block_size - mod) % cipher.block_size
if padding > 0:
value += NULL_BYTE + random_string(padding - 1)
return cipher.encrypt(value)
def decode_aes(value: bytes, key: str) -> str:
cipher = AES.new(key[:32], AES.MODE_ECB)
decrypted = cipher.decrypt(value).decode('utf8')
return decrypted.rsplit(NULL_BYTE, 1)[0]
添加回答
舉報