pycrypto encrypt/decrypt,解密时丢失部分加密字符串

pycrypto encrypt/decrypt, losing part of encrypted string when decrypting

我正尝试 encrypt/decrypt 在 python 中使用 pycrypto。在大多数情况下,一切都进行得很顺利,但我在解密时遇到了一个奇怪的问题 data.I 我尝试 encrypt/decrypt 一些 jpg 文件进行测试,尽管它们 encrypt/decrypt 没有问题,但解密的文件不能opened/are 已损坏。为了找到问题所在,我保存了一个带有类似于 "test this file for integrity blah blah blah" 的随机句子的文本文件,并且只有在“.... integrity blah blah blah”之后才能正确解密,完整性之前的所有内容仍然是乱码。我对 AES 不是那么了解,但我假设这是一个 encoding/decoding 或填充错误。

这是我的代码:

#encryption
iv = Random.new().read( AES.block_size)

filePath = input("Path to file for encryption: ")
selFile = open(filePath, 'rb')
getBytes = bytes(selFile.read())

encPW = input("Enter password: ")
hashpw = hashlib.sha256(encPW.encode('UTF-8').digest())

destination = input("Destination path for encrypted file: ")

aes = AES.new(hashpw, AES.Mode_CFB, iv)
encFile = base65.b64encode(aes.encrypt(getBytes))

writetofile = open(destination, 'wb')
writetofile.write(encFile)
writetofile.close()
print("Encryption successful")

#Decryption
iv = Random.new().read( AES.block_size)

filePath = input("Path to file for decryption: ")
selFile = open(filePath, 'rb')
getBytes = bytes(selFile.read())

decPW = input("Enter password: ")
hashdecpw = hashlib.sha256(encPW.encode('UTF-8').digest())

destination = input("Destination path for decrypted file: ")

aes = AES.new(hashdecpw, AES.Mode_CFB, iv)
decFile = aes.decrypt(getBytes)

writetofile = open(destination, 'wb')
writetofile.write(decFile)
writetofile.close()
print("Decryption successful")

关于可能导致第一个字符丢失并阻止我正确 encrypting/decrypting 个文件的任何想法?

您至少有三个问题:

  • 您的意思可能是 hashlib.sha256(encPW.encode('UTF-8')).digest() 而不是 hashlib.sha256(encPW.encode('UTF-8').digest())(右大括号位置错误)

  • 您在将密文写入文件之前使用 Base64 对其进行编码。在解密之前从文件中读回后,您忘记了对其进行解码。例如:

    getBytes = base64.b64decode(bytes(selFile.read()))
    
  • 这很重要:在解密过程中,您需要与用于加密的完全相同的 IV。 IV 不是秘密,但对于您使用同一密钥完成的每次加密,它都必须是唯一的。一般IV写在密文前面,读回解密

    #encryption
    encFile = base64.b64encode(iv + aes.encrypt(getBytes))
    
    #decryption
    getBytes = base64.b64decode(bytes(selFile.read()))
    iv = getBytes[:16]
    aes = AES.new(hashdecpw, AES.Mode_CFB, iv)
    decFile = aes.decrypt(getBytes[16:])
    

你生成一个新的IV,分别加密和解密,会产生这样的问题。这是我推荐的做法:

def encrypt(inpath, outpath, password):
    iv = Random.new().read(AES.block_size)
    with open(inpath, "rb") as f:
        contents = f.read()
    # A context manager automatically calls f.close()
    key = pbkdf2.crypt(password, "")
    # See notes

    aes = AES.new(key, AES.Mode_CFB, iv)
    encrypted = aes.encrypt(contents)
    with open(outpath, "wb") as f:
        f.write(iv + b":")
        f.write(encrypted)
    print("Encryption successful")


def decrypt(inpath, outpath, password):
    with open(inpath, "rb") as f:
        contents = f.read()

    iv, encrypted = contents.split(b":")
    key = pbkdf2.crypt(password, "")
    aes = AES.new(key, AES.Mode_CFB, iv)

    decrypted = aes.decrypt(contents)
    with open(outpath, "wb") as f:
        f.write(decrypted)
    print("Decryption successful")

一些注意事项:

  • IV并不意味着是秘密的,因此可以随机生成一次,然后写入文件以供以后解密使用(如本例所示)

  • 散列算法不足以派生密钥,这就是为什么有称为密钥派生算法的特殊工具(如 python 中的 PBKDF2)。请改用它们!

我没有亲自测试过这段代码,所以它可能无法正常工作。