PyCryptoDome cipher.encrypt 将空白文本保存到加密文件

PyCryptoDome cipher.encrypt saving blank text to encrypted file

我在加密 accountfile 路径下的文件内容时遇到很多问题。 加密确实有效,因为解密成功输出了将路径保存到文件的版本的帐户文件的路径。代码运行成功,没有错误,但保存的加密文件在加密时最终为空白。如何让ptext的内容加密成功?

def encrypt_account(path, filename, accountfile):
    c_file = PurePath(path).parent / (PurePath(filename).parent.name + "c.txt")
    file3 = open(c_file, 'rb')
    byteskey = file3.read(32)
    file3.close()
    ckey = bytes(byteskey)

    cipher = AES.new(ckey, AES.MODE_CBC)
    ptext = open(str(accountfile)).read()# this is the account file
    ciphertext = cipher.encrypt(pad(bytes(ptext, "utf-8"), AES.block_size))

    with open(str(path.parent / accountfile.stem) + ".enc", 'wb')as c_file:
        c_file.write(cipher.iv)
        c_file.write(ciphertext)
    #c_file.close()
    #os.remove(accountfile)

这是一个有效的例子,但是请不要将它用于任何敏感的事情,因为它不安全。

正确使用密码学原语是困难;你应该改用 higher-level 比你我更聪明的人编写并证明在正确使用时是安全的食谱。我对 Python 的建议是 Fernet

除此之外,您可以编写一些秘密数据并生成一个密钥,然后 运行 脚本并取回您的秘密数据:

$ echo "Very secret data" > secret.txt
$ dd if=/dev/urandom bs=1 count=32 > key.dat
32 bytes transferred
$ python so64569401.py
b'Very secret data\n'

但是,如前所述,这是 安全的,因为数据未经过身份验证;密文可以被篡改,你不会知道数据不是你放回的。例如,如果我删除第一个加密调用,然后修改加密文件中的单个字节和 运行 脚本再次:

$ hexf secret.txt.enc
$ python so64569401.py
b'Very secRet data\n'

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad


def read_key(filename) -> bytes:
    with open(filename, "rb") as f:
        key = f.read(32)
        assert len(key) == 32
        return key


def encrypt_file(filename: str, key: bytes) -> str:
    with open(filename, "rb") as f:
        data = f.read()

    cipher = AES.new(key, AES.MODE_CBC)
    cipher_data = cipher.encrypt(pad(data, AES.block_size))

    encrypted_filename = filename + ".enc"

    with open(encrypted_filename, "wb") as f:
        f.write(cipher.iv)
        f.write(cipher_data)

    return encrypted_filename


def decrypt_file(filename: str, key: bytes) -> bytes:
    with open(filename, "rb") as f:
        iv = f.read(AES.block_size)
        cipher_data = f.read()

    cipher = AES.new(key, AES.MODE_CBC, iv=iv)
    return unpad(cipher.decrypt(cipher_data), AES.block_size)


def main():
    key = read_key("key.dat")
    encrypted_filename = encrypt_file("secret.txt", key)
    decrypted_data = decrypt_file(encrypted_filename, key)
    print(decrypted_data)


if __name__ == "__main__":
    main()