Python 3 PyCrypto IV 的长度必须为 16 字节


所以我一直在尝试基于 github

pycrypto 指南链接到 github 构建一个 AES 加密程序,但是当我去解码时会出现错误:

Traceback (most recent call last):
File "/home/pi/Desktop/aes/newAES.py", line 24, in <module>
    print(decrypt(key,msg,iv))
File "/home/pi/Desktop/aes/newAES.py", line 13, in decrypt
    cipher = AES.new(key,AES.MODE_CFB)
File "/usr/lib/python3/dist-packages/Crypto/Cipher/AES.py", line 94, in new
    return AESCipher(key, *args, **kwargs)
File "/usr/lib/python3/dist-packages/Crypto/Cipher/AES.py", line 59, in __init__
blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
File "/usr/lib/python3/dist-packages/Crypto/Cipher/blockalgo.py", line 141, in __init__
    self._cipher = factory.new(key, *args, **kwargs)
ValueError: IV must be 16 bytes long

我的代码是:

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
def encrypt(key,msg):
    if key == 0:
        key=get_random_bytes(16)
        print("key: "+key)
    iv = get_random_bytes(16)
    print('iv: '+str(iv))
    cipher = AES.new(key,AES.MODE_CFB,iv)
    ciphertext= cipher.decrypt(msg)
    return("your encrypted message: "+str(ciphertext))
def decrypt(key,ciphertext,iv):
    cipher = AES.new(key,AES.MODE_CFB)
    msg = cipher.decrypt(ciphertext)
ed = input('(e)ncrypt or (d)ecrypt: ')
if ed=='e':
    key = input('16 digit key: ')
    msg = input('message: ')
    print(encrypt(key,msg))
elif ed =='d':
    key = input('16 digit key: ')
    iv = bytes(input('iv: '),'utf-8')
    msg = bytes(input('encrypted message:'),'utf-8')
    print(decrypt(key,msg,iv))

我将不胜感激在解决此问题方面提供的任何帮助,希望这不是一些愚蠢的错误

iv的问题

在于它由随机字节组成,但它作为字符串被读取到您的程序中。 对该字符串调用 bytes 不会执行预期操作。

>>> iv = b'xbax0eyO8x17xcfx97=xf2&l34#('
>>> siv = str(iv)
>>> siv
"b'\xba\x0eyO8\x17\xcf\x97=\xf2&l34#('"   # Note 'b' is part of the string
>>> biv = bytes(siv, 'utf-8')
>>> biv
b"b'\xba\x0eyO8\x17\xcf\x97=\xf2&l34#('"  # Now there are two 'b's!

您可以使用ast.literal_eval解决此问题:

>>> ast.literal_eval(siv)
b'xbax0eyO8x17xcfx97=xf2&l34#('

这是您代码的工作版本 - 我消除了复制/粘贴iv的需要,但关于输入字节的相同观察也适用于密文。

import ast
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

def encrypt(key, msg):
    iv = get_random_bytes(16)
    cipher = AES.new(key, AES.MODE_CFB, iv)
    ciphertext = cipher.encrypt(msg)    # Use the right method here
    return iv + ciphertext

def decrypt(key, ciphertext):
    iv = ciphertext[:16]
    ciphertext = ciphertext[16:]
    cipher = AES.new(key, AES.MODE_CFB, iv)
    msg = cipher.decrypt(ciphertext)
    return msg.decode("utf-8")

if __name__ == "__main__":
    ed = input("(e)ncrypt or (d)ecrypt: ")
    if ed == "e":
        key = input("16 digit key: ")
        msg = input("message: ")
        print("Encrypted message: ", encrypt(key, msg))
    elif ed == "d":
        key = input("16 digit key: ")
        smsg = input("encrypted message: ")
        msg = ast.literal_eval(smsg)
        print("Decrypted message: ", decrypt(key, msg))

操作中的代码:

(e)ncrypt or (d)ecrypt: e
16 digit key: abcdabcdabcdabcd
message: Spam, spam, spam
Encrypted message:  b'xa4?xa9RI>x1fxb5*xb2,NWNx0cxfd"yB|x1fx82x96xd5xb4xd4x1d&x8bMxdbx07'
(e)ncrypt or (d)ecrypt: d
16 digit key: abcdabcdabcdabcd
encrypted message: b'xa4?xa9RI>x1fxb5*xb2,NWNx0cxfd"yB|x1fx82x96xd5xb4xd4x1d&x8bMxdbx07'
Decrypted message:  Spam, spam, spam

最新更新