使用 pyaes 进行 AES 加密时,明文块必须为 16 字节错误
plaintext block must be 16 bytes error when using pyaes for AES Encryption
我正在尝试使用 pyaes
进行 AES 加密。
我下面的代码是 运行 完美。
text = 'Hello world !!!!'
encrypter = pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001')
encrypted = base64.b64encode(encrypter.encrypt(text))
print(encrypted)
但是,当我将文本值更改为
text = 'rO0ABXVyAAJbQqzzF/gGCFTgAgAAeHAAAAAI3z7LN2KbyKE='
它returns有错误。
Traceback (most recent call last):
File "/home/path/cryptolib/test.py", line 54, in <module>
encrypted = base64.b64encode(encrypter.encrypt(text))
File "/home/path/pyaes/aes.py", line 389, in encrypt
raise ValueError('plaintext block must be 16 bytes')
ValueError: plaintext block must be 16 bytes
我不是 AES
方面的专家,所以可能缺少基础知识。
我不能使用 pycrypto
,因为我正在为 redshift 开发 UDF
,根据我的发现,那里不支持 pycrypto
。
pyaes#AESModeOfOperationCBC
only allows the encryption of a text that is exactly one block (16 bytes) long. For longer texts BlockFeeder必须使用:
import pyaes, base64
#Encryption
text = 'rO0ABXVyAAJbQqzzF/gGCFTgAgAAeHAAAAAI3z7LN2KbyKE='
encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
ciphertext = encrypter.feed(text)
ciphertext += encrypter.feed()
ciphertext = base64.b64encode(ciphertext)
#Decryption
decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
decrypted = decrypter.feed(base64.b64decode(ciphertext))
decrypted += decrypter.feed()
print('>' + decrypted + '<\n')
BlockFeeder 也会自动执行padding。填充是将数据添加到消息的末尾,直到长度对应于块长度的整数倍(通常很重要,但与您的示例无关,因为长度条件已经满足)。
编辑:
Encrypter#feed(<plaindata>)
缓冲明文,加密除最后一个块(如果最后一个块完整)或最后两个块(如果最后一个块不完整)以外的数据,returns加密的数据。最后的 Encrypter#feed()
调用发出明文结束的信号,触发余数的填充和加密,以及 returns 加密数据。这可以是
用以下代码片段说明:
import pyaes
#Encryption
encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
ciphertext = encrypter.feed ('0123456789ABCDEF') # 1. block buffered, ciphertext = ''
ciphertext += encrypter.feed('0123456789ABCDE') # 1. and incomplete 2. block buffered, ciphertext += ''
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed('F') # 1. block flushed, 2. block buffered, ciphertext += '<encrypted 1. block>'
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed('0123456789ABCDEF') # 2. block flushed, 3. block buffered, ciphertext += '<encrypted 2. block>'
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed('0123456') # 3. and incomplete 4. block buffered, ciphertext += ''
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed() # 3. and padded 4. block flushed, ciphertext += '<encrypted 3. and 4. padded block >'
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
#Decryption
decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
decrypted = decrypter.feed(ciphertext)
decrypted += decrypter.feed()
print('>' + decrypted + '<\n')
示例中,最后一段纯文本不完整。如果纯文本的最后一个块已经完成,则填充一个额外的完整块。这里使用的padding是PKCS7.
我正在尝试使用 pyaes
进行 AES 加密。
我下面的代码是 运行 完美。
text = 'Hello world !!!!'
encrypter = pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001')
encrypted = base64.b64encode(encrypter.encrypt(text))
print(encrypted)
但是,当我将文本值更改为
text = 'rO0ABXVyAAJbQqzzF/gGCFTgAgAAeHAAAAAI3z7LN2KbyKE='
它returns有错误。
Traceback (most recent call last):
File "/home/path/cryptolib/test.py", line 54, in <module>
encrypted = base64.b64encode(encrypter.encrypt(text))
File "/home/path/pyaes/aes.py", line 389, in encrypt
raise ValueError('plaintext block must be 16 bytes')
ValueError: plaintext block must be 16 bytes
我不是 AES
方面的专家,所以可能缺少基础知识。
我不能使用 pycrypto
,因为我正在为 redshift 开发 UDF
,根据我的发现,那里不支持 pycrypto
。
pyaes#AESModeOfOperationCBC
only allows the encryption of a text that is exactly one block (16 bytes) long. For longer texts BlockFeeder必须使用:
import pyaes, base64
#Encryption
text = 'rO0ABXVyAAJbQqzzF/gGCFTgAgAAeHAAAAAI3z7LN2KbyKE='
encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
ciphertext = encrypter.feed(text)
ciphertext += encrypter.feed()
ciphertext = base64.b64encode(ciphertext)
#Decryption
decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
decrypted = decrypter.feed(base64.b64decode(ciphertext))
decrypted += decrypter.feed()
print('>' + decrypted + '<\n')
BlockFeeder 也会自动执行padding。填充是将数据添加到消息的末尾,直到长度对应于块长度的整数倍(通常很重要,但与您的示例无关,因为长度条件已经满足)。
编辑:
Encrypter#feed(<plaindata>)
缓冲明文,加密除最后一个块(如果最后一个块完整)或最后两个块(如果最后一个块不完整)以外的数据,returns加密的数据。最后的 Encrypter#feed()
调用发出明文结束的信号,触发余数的填充和加密,以及 returns 加密数据。这可以是
用以下代码片段说明:
import pyaes
#Encryption
encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
ciphertext = encrypter.feed ('0123456789ABCDEF') # 1. block buffered, ciphertext = ''
ciphertext += encrypter.feed('0123456789ABCDE') # 1. and incomplete 2. block buffered, ciphertext += ''
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed('F') # 1. block flushed, 2. block buffered, ciphertext += '<encrypted 1. block>'
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed('0123456789ABCDEF') # 2. block flushed, 3. block buffered, ciphertext += '<encrypted 2. block>'
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed('0123456') # 3. and incomplete 4. block buffered, ciphertext += ''
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
ciphertext += encrypter.feed() # 3. and padded 4. block flushed, ciphertext += '<encrypted 3. and 4. padded block >'
print("Current length of ciphertext: " + str(len(ciphertext)) + " Bytes\n")
#Decryption
decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC('my_test_key_0001', 'my_test_vec_0001'))
decrypted = decrypter.feed(ciphertext)
decrypted += decrypter.feed()
print('>' + decrypted + '<\n')
示例中,最后一段纯文本不完整。如果纯文本的最后一个块已经完成,则填充一个额外的完整块。这里使用的padding是PKCS7.