Проблема в многопоточном шифровании с питоном - PullRequest
0 голосов
/ 03 мая 2019

Я хочу написать скрипт для шифрования указанной папки файловЯ нахожу скрипт для этой работы от 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 голосов
/ 05 мая 2019

Прежде всего, вы должны установить, что шифрование AES действительно является фактором, который делает это медленным.Весьма вероятно, что ввод / вывод гораздо важнее.Вы можете проверить это, удалив шифрование из уравнения и просто скопировав файлы.

Обычно диски (и даже твердотельные накопители) быстрые для последовательного чтения / записи.Поэтому было бы плохой идеей считывать файлы многопоточным способом из одной папки.Если вы должны использовать многопоточность, то создайте один поток для чтения / записи файлов, а затем распределите фрагменты по нескольким потокам для шифрования.

Однако шифрование CBC неочень полезно для этого, поскольку каждый блок зависит от выходных данных предыдущего блока (т. е. он является последовательным), например, использование режима CTR позволяет одновременно шифровать отдельные фрагменты.Кроме того, в режиме CTR вы можете кэшировать поток ключей , что также может значительно ускорить работу.Вы можете кэшировать поток ключей, зашифровав порции, состоящие из нулевых байтов.

Для действительно быстрого шифрования вы также можете посмотреть на произвольный доступ с использованием файлов отображения памяти.Это может быть быстрее, чем потоковые файлы, хотя обычно O / S уже кэширует файл в памяти в любом случае.

Если виновником является AES, вам следует посмотреть, включен ли AES-NI.PyCryptodome, похоже, поддерживает AES-NI, поэтому следует использовать для ускорения шифрования / дешифрования AES.

Наконец, если вы недостаточно умны, чтобы удалить getKey(password) из циклатогда никто не сможет тебе помочь.Пожалуйста, профилируйте вашу заявку.Вы должны заменить getKey(password) на функцию получения ключа на основе пароля, такую ​​как PBKDF2, чтобы обеспечить безопасность для «обычных» пользовательских паролей.

...