提问人:user21815993 提问时间:11/14/2023 最后编辑:Maarten Bodewesuser21815993 更新时间:11/14/2023 访问量:65
使用带有 CBC 模式的 AES 将 UTF-16 加密为 UTF-16
Using AES with CBC mode to encrypt UTF-16 into UTF-16
问:
我在我的应用程序中使用 pycryptodome 进行加密。 应用程序的一部分要求我打开一个文件,加密文件中的数据,并加密文件的名称。我使用了带有 CBC 模式的 AES(因为它是我在处理文件时的首选方法),并且文件加密类效果很好:
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(我都尝试了,它们都失败了)。所以我想知道,在这种情况下,有没有办法将字符串加密成字符串?
顺便说一句,我知道我在标题中说过,我想使用带有 CBC 模式的 AES 进行加密,这仍然是正确的。但是,如果没有其他方法可以解决这个问题,那么我可以使用其他加密方法,只要它们与AES加密一样安全和快速。
答:
我可以看到不少于三个选项:
FPS 或格式保留加密:这可能是最符合您要求的选项。它将使用任何字母将文本加密为具有相同字母和大小的内容。问题在于,这是一项非常困难的任务,并且 FF1 和 FF3 等 FPS 的实现并不常见。FPS 安全是一个棘手的话题,它不会那么快 - 但可能足够快。
CBC + 基数转换:可以使用任何方案(如 CBC)进行加密,然后对仅包含对文件名有效的字符(可能点除外)的字母表中的索引执行基数转换。这将扩展文件名,因为 CBC 有开销,并且因为密文使用字节的所有可能值。
一个。如果要使用所有可能的字符(对于特定操作系统),则在用于较大的密文时,基本转换可能会很棘手;如果实施不当,它会占用大量 CPU。
b.为了方便起见,您可以使用 base64url 对加密文件进行编码 名称,例如,制作它,但要注意文件名和路径的大小限制。
<base64offullfilename>.b64
将其存储为元信息:可能最简单的选择是将文件名存储为密文的一部分,然后使用序列号或类似信息(例如)。如果你这样做,你只需要将文件名与内容区分开来。如果您不想自己这样做,您可以将文件放入存档中并对其进行加密。
encrypted_file_001.bin
在这一点上,你可能必须先做出选择,然后才能进行任何实现。由于第一个确实需要很多理解,第二个是相当多的工作,我建议采取选项 2b 或 3。
言论:
- 并非所有 UTF-16 字符串都是有效的文件名;冒号和斜杠之类的东西通常不会放在文件名中;
- base64URL 也被明确地用于文件名是安全的。
评论
b''
IsADirectoryError
open()
/
.
..