python多线程加密问题

时间:2019-05-03 15:04:48

标签: python encryption aes

我想编写一个脚本来加密指定的文件夹文件
我从github
找到了用于这项工作的脚本 但是我加密大文件夹的工作很慢
我现在想使用多线程来加快速度
但是我无法使用线程库

我的低速加密文件夹中现有文件的代码

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

def discoverFiles(startpath):
    extensions = [
        'mp3'
    ]

    for dirpath, dirs, files in os.walk(startpath):
        for i in files:
            absolute_path = os.path.abspath(os.path.join(dirpath, i))
            ext = absolute_path.split('.')[-1]
            if ext in extensions:
                yield absolute_path

def encrypt(key, filename):
    chunksize = 64 * 1024
    outputFile = i + '.enc'
    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()

path = raw_input("Enter your path : ") ; path = str(path)
password = raw_input("Enter your key : ") ; password = str(password)

x = discoverFiles(path)

for i in x:
    encrypt(getKey(password),i)
    os.remove(i)

对于这项工作,我知道我们必须使用线程库,但是我不能使用该库

请帮我完成这项工作...

1 个答案:

答案 0 :(得分:0)

首先,您应该确定AES加密确实是导致此速度变慢的因素。 I / O非常重要。您可以通过从等式中删除加密并仅复制文件来进行检查。

通常,磁盘(甚至是SSD)对于顺序读取/写入来说速度很快。因此,从单个文件夹中以多线程方式读取文件将是一个坏主意。如果必须使用多线程,则创建一个线程来读写文件,然后将块分配到多个线程上进行加密。

但是,CBC加密对此并不是很有用,因为每个块取决于前一个块的输出(即它是顺序的),例如使用CTR模式将允许同时对单独的块进行加密。此外,使用CTR模式,您可以缓存密钥流,这也可以大大加快操作速度。您可以通过加密零字节组成的块来缓存密钥流。

对于真正快速的加密,您不妨使用内存映射文件查看随机访问。 可能比流式传输文件要快,尽管通常操作系统通常已经将文件缓存在内存中。

如果是AES的元凶,那么您应该查看AES-NI是否已启用。 PyCryptodome似乎支持AES-NI,因此应该用于加速AES加密/解密。

最后,如果您不够聪明,无法将getKey(password)从循环中删除,那么没人会帮助您。请分析您的应用程序。您应该用基于密码的密钥派生功能(例如PBKDF2)替换getKey(password),以保护“公用”用户密码。