使用AES模式cbc将utf-18加密为utf-18

问题描述 投票:0回答:1

我在我的应用程序中使用 pycryptodome 进行加密。 该应用程序的一部分要求我打开一个文件,加密文件中的数据,并加密文件的名称。我使用了 AES 模式 cbc(因为这是我处理文件时的首选方法),并且文件加密类效果很好:

class Cipher:
    def __init__(self, password: str, key: bytes = None):
        self.key = PBKDF2(password, key if key else password_as_key(password), dkLen=32)
        self.cipher = AES.new(self.key, AES.MODE_CBC, iv=get_random_bytes(16))

    def encrypt(self, data: bytes) -> bytes:
        return self.cipher.encrypt(pad(data, AES.block_size)) + self.cipher.iv

    # decryption is the same as encryption, but it's necessary to remove the IV before
    def decrypt(self, data: bytes) -> bytes:
        encrypted_data = data[:-16]
        iv = data[-16:]
        self.cipher = AES.new(self.key, AES.MODE_CBC, iv=iv)
        return unpad(self.cipher.decrypt(encrypted_data), AES.block_size)

我也想使用这种加密进行名称加密,但有一个问题。加密文件名时,我需要将文件保存在文件系统上,所以我不能只将名称保存为一堆字节。但是,简单地解码文本是不可能的,因为 AES 会进行大量字节移位,因此我无法确保文件保持任何编码,无论是 utf-8、utf-16 甚至是 base64 (我都试过了,但都失败了)。所以我想知道,在这种情况下有什么方法可以将字符串加密为字符串吗?

顺便说一句,我知道我在标题中说过我想使用 AES 模式 cbc 进行加密,这仍然是事实。但如果没有其他方法来解决这个问题,那么我可以使用其他加密方法,只要它们像 AES 加密一样安全和快速。

python string encryption aes pycryptodome
1个回答
0
投票

我可以看到不少于三个选项:

  1. FPS 或格式保留加密:这可能是最适合您的要求的选项。它将使用任何字母表将文本加密为具有相同字母表和大小的内容。问题是这是一项相当困难的任务,而且 FF1 和 FF2 等 FPS 的实现并不常见。

  2. CBC + 基数转换:可以使用任何方案(例如 CBC)进行加密,然后对字母表中的索引执行基数转换,该字母表仅包含对文件名有效的字符 - 可能除了点之外。这将扩展文件名,因为 CBC 有开销,并且密文使用一个字节的所有可能值。当用于较大的密文时,基数转换可能会很棘手;如果实施不当,会占用大量 CPU。

  3. 将其存储为元信息:可能最简单的选择是将文件名存储为密文的一部分,然后使用序列号或类似信息(例如

    encrypted_file_001.bin
    )。如果这样做,您只需区分文件名和内容即可。如果您不想自己执行此操作,您可以将文件放入存档中并对其进行加密。

此时,您可能必须先进行选择,然后才能进行任何实施。由于第一个确实需要大量理解,第二个需要大量工作,我建议采用选项 3。

© www.soinside.com 2019 - 2024. All rights reserved.