【问题标题】:Decrypt a encrypted secret using PyCrypto AES & sha256使用 PyCrypto AES 和 sha256 解密加密的秘密
【发布时间】:2019-05-13 05:54:33
【问题描述】:

我在一个文件中有一条加密消息,由以下代码加密。 我写了一个函数来解密这条消息。我知道用来加密它的密码。

但我收到以下错误:

python3 decrypt.py enim_msg.txt 
Traceback (most recent call last):
  File "decrypt.py", line 45, in <module>
    print(":: Decrypted: \n" + bytes.decode(decrypted))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 2: invalid start byte

请问我该如何解决这个问题? 我的解密功能有问题吗?

我的代码:

加密函数

import os
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Hash import SHA256

def encrypt(key, filename):
    chunksize = 64*1024
    outputFile = "en" + filename
    filesize = str(os.path.getsize(filename)).zfill(16)
    IV = Random.new().read(16)

    encryptor = AES.new(key, AES.MODE_CBC, IV)

    with open(filename, 'rb') as infile:
        with open(outputFile, 'wb') as outfile:
            outfile.write(filesize.encode('utf-8'))
            outfile.write(IV)

            while True:
                chunk = infile.read(chunksize)

                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += b' ' * (16 - (len(chunk) % 16))

                outfile.write(encryptor.encrypt(chunk))

def getKey(password):
    hasher = SHA256.new(password.encode('utf-8'))
    return hasher.digest()

我写的解密函数

def decrypt(enc, password):
    #print(":: enc => " + enc)
    private_key = hashlib.sha256(password.encode("utf-8")).digest()
    iv = enc[:16]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)

    return cipher.decrypt(enc[16:])

我如何调用这个函数

password = "azerty123"
secret_file_path = sys.argv[1]

the_file = open(secret_file_path, "rb")
encrypted = the_file.read()
decrypted = decrypt(encrypted, password)
the_file.close()

print(":: Decrypted: \n" + bytes.decode(decrypted))

【问题讨论】:

  • 我不太了解 Python - 但我知道在加密方面将任何内容存储为字符串是一个坏主意。加密数据、密钥等本质上都是二进制数据——你也应该以这种方式存储它们。您不能将任意二进制文件转换为字符串并返回。
  • 哇,我见过很多“不平衡”的加密/解密函数,但这个占了上风。作为开发人员,您怎么能认为这会起作用?您的加密/解密功能应该反过来做同样的事情。为什么filesize 是一个字符串?
  • 哦,我明白了,它只是一个 16 字节/字符的十进制字符串,这只是次优的。玉。我看不到您在解密期间处理此问题的任何地方。块可能用空格填充的方式是绝对错误的,没有完全检索到的块可能会让这个功能失败,例如当缓冲区大小不是块大小的倍数时。加密只是一个等待发生的错误。

标签: python encryption aes sha256


【解决方案1】:

bytes.decrypt() 函数默认需要一个 UTF-8 编码的字符串。但并非每个字节序列都是有效的 UTF-8 序列。在您的情况下,cipher.decrypt()(可能返回 any 字节序列)返回了一个字节序列,它不是有效的 UTF-8 序列。因此bytes.decode() 函数引发了错误。

cipher.decrypt() 返回非 UTF-8 字符串的实际原因是您的代码中存在错误:

您的加密文件格式包含非 utf-8 数据。它的格式是这样的:

  • 16 字节长度信息(未加密,UTF-8 编码)
  • 16 字节 IV(未加密,二进制,即非 UTF-8 编码)
  • n 字节有效负载(加密,UTF-8 编码)

您必须确保在解密时只解码文件的一部分,即 UTF-8 编码。此外,您必须确保仅解密文件的加密部分(如您的 cmets 中所述)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2014-01-18
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多