带填充的 AES 实施

AES 代表高级加密标准,是一种广泛使用的对称加密算法,由美国国家标准与技术研究院 (NIST) 于 2001 年制定。对称密钥加密算法仅使用一个密钥来完成加密和解密任务。AES 是作为当时流行但过时的数据加密标准 (DES) 算法的后继者引入的。

AES 是一种分组密码,这意味着它将消息分成块并单独加密或解密。这些块的大小是固定的,即 128 位。

加密是隐藏或更改消息状态的过程,以便只有收件人才能理解该消息。

如何用Python编写加密程序可以参考这篇文章。

在这篇文章中,我们将详细了解 AES 及其使用填充的实现。

什么是 AES?

高级加密标准算法是一种对称密钥加密算法,因此它只使用一个密钥进行加密和解密。它也是一种分组密码,意味着它将消息分为每个固定大小 128 位的块。AES 算法的密钥大小可以是 128,192 和 256 位。对于每个密钥大小,该算法会发生许多轮。AES-128 使用 10 轮,AES-192 使用 12 轮,AES-256 使用 14 轮。这是一个可以更好地理解 AES 的框图。

相关:访问这篇文章以了解 RSA。

AES 框图

在即将推出的实现中,我们使用一种称为 ECB 的电子密码本缩写,由于其简单性而用于加密算法。在 ECB 中,明文被分为固定大小的块,通常为 64 或 128 位。虽然简单,但在尝试实现大数据时不建议使用。

由于AES是固定大小的块算法,有时为了满足要求,我们需要添加额外的位来填充空块。这个过程称为填充。我们将在实现中使用 PKCS#7 填充。此填充是另一个称为 PKCS#5 的填充的后继者。这两种填充方案之间的主要区别在于块大小。

虽然 PKCS5 填充仅适用于大小为 8 字节的块,但我们可以将 PKCS7 填充用于块大小在 0 到 255 字节之间的任何算法。

我们将使用两个库 cryptographypycryptodome来实现 AES。

使用加密技术实现 AES

在开始编写代码之前,我们需要确保安装该cryptography库。

pip install cryptography

现在让我们看看代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.padding import PKCS7
from cryptography.hazmat.backends import default_backend
import base64
def encrypt(plaintext, key):
    cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
    encryptor = cipher.encryptor()
    padder = PKCS7(algorithms.AES.block_size).padder()
    padded_data = padder.update(plaintext) + padder.finalize()
    ciphertext = encryptor.update(padded_data) + encryptor.finalize()
    encodedciphertext = base64.b64encode(ciphertext)
    return encodedciphertext
 def decrypt(ciphertext, key):
    cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
    decryptor = cipher.decryptor()
    decodedciphertext = base64.b64decode(ciphertext)
    padded_data = decryptor.update(decodedciphertext) + decryptor.finalize()
    unpadder = PKCS7(algorithms.AES.block_size).unpadder()
    plaintext = unpadder.update(padded_data) + unpadder.finalize()
    return plaintext
key = b'\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10' \
      b'\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10'
plaintext = input("Enter the plaintext: ").encode()
enc = encrypt(plaintext, key)
print("The encrypted message is :", enc)
dec = decrypt(enc, key)
print("The decrypted message is:", dec.decode('utf-8'))

在前四行中,我们正在导入必要的包。hazmat 是加密库的一个包,具有加密所需的所有原语。密码模块包含我们将用于加密和解密的对称密码。algorithms模块包含所有必要的算法,如 DES、AES 等。模块modes存储ECB、CBC、CTR等加密模式。

我们正在从模块导入 PKCS#7 填充方案padding

default_backend模块负责执行加密。

我们正在导入base64用于编码的模块。

我们正在创建两个函数:加密和解密。加密函数将我们在第 23 行中获得的明文和我们在第 21 行中创建的密钥作为参数,并通过使用 AES 算法、ECB 模式和使用填充的 default_backend 执行加密来返回编码的密文作为输出PKCS#7

我们在上一个函数中获得的密文作为参数与密钥一起传递给解密函数。这里发生了前一个函数中发生的相反过程。通过取消填充密文,将密文解码为纯文本。

AES 使用大小为 128,192 和 256 位的密钥。所以我们这里提供的密钥应该是确定的大小。

调用这两个函数并将结果存储在名为 的变量中enc and dec这些加密和解密的消息被打印在屏幕上。

使用密码学库实现 AES

使用 Pycryptodome 实现 AES

在开始编码之前,我们需要安装 pycryptodome 库。

pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
import base64
def encrypt(plaintext, key):
    cipher = AES.new(key, AES.MODE_ECB)
    padtext = pad(plaintext, AES.block_size)
    ctext = cipher.encrypt(padtext)
    encodedctext= base64.b64encode(ctext)
    return encodedctext
def decrypt(ciphertext, key):
    cipher = AES.new(key, AES.MODE_ECB)
    decodedctext = base64.b64decode(ciphertext)
    padded_plaintext = cipher.decrypt(decodedctext)
    plaintext = unpad(padded_plaintext, AES.block_size)
    return plaintext
key = get_random_bytes(16)
plaintext = input("Enter the plaintext: ").encode()
enc= encrypt(plaintext, key)
print("The encrypted data is:", enc)
decrypted = decrypt(enc, key)
print("The decrypted data is:", decrypted.decode('utf-8'))

我们从 Crypto 包中导入 AES 算法。Padding模块中,我们导入 pad 和 unpad。我们还导入 random_bytes 来生成密钥。导入base64进行编码。就像前面的示例一样,我们正在创建加密和解密函数。

加密函数将我们输入的纯文本和我们随机生成的密钥作为参数,并在填充后返回编码文本,并使用 AES 算法进行编码。

解密函数采用密文和密钥来返回解密或纯文本。它执行与加密功能相反的操作。密文被解码并取消填充,然后作为plaintext.

get_random_bytes用于生成 16 字节(128 位)密钥我们正在从用户那里获取纯文本的输入。

调用加密和解密这两个函数,并将结果分别存储在名为 enc 和 dec 的变量中。

结果被打印。

使用 Pycryptodome 实施 AES

结论

AES 代表高级加密标准算法,是作为 DES 的后继者推出的。它是一种对称密钥加密,因此仅使用一个密钥进行加密和解密。它也是一种分组密码,可将纯文本分解为固定大小的块。

cryptography我们已经看到了 AES 使用 python和两个库的实现pycryptodome

在实现中,我们采用明文,对其应用 AES 算法,用一些位填充消息,然后对消息进行编码以返回密文。

密文作为参数传递给解密函数,解密函数将消息解填充并对其进行解码。然后返回明文。

参考

请访问加密包的 PyPI 文档。

Pycryptodome 库。