Пихон. Невозможно успешно предоставить пароль для команды расшифровки стандартного ввода 7-zip CMD - PullRequest
1 голос
/ 25 мая 2020

Я использую версию 7 zip для командной строки 7za.exe для моих нужд сжатия / шифрования и распаковки / дешифрования. Для повышения безопасности я не выполняю команду в CMD с паролем. Скорее, я передаю пароль с помощью подпроцесса и передаю его на стандартный ввод CMD.

Вот моя функция выполнения, которая используется для запуска системных команд с вводом.

    def execute(self, cmd : typing.List[str], input: typing.Optional[bytes] = None, verbose=False, debug=False, normal_priority=False):
        if verbose:
            print(cmd)
        creationflags = subprocess.CREATE_NO_WINDOW
        if normal_priority:
            creationflags |= subprocess.NORMAL_PRIORITY_CLASS
        else:
            creationflags |= subprocess.BELOW_NORMAL_PRIORITY_CLASS

        if debug:
            process = subprocess.Popen(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, stdin=subprocess.PIPE,creationflags=creationflags)
        else:
            process = subprocess.Popen(cmd, shell=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
                                       stdin=subprocess.PIPE, creationflags=creationflags)
        if input:
            process.stdin.write(input)
            process.stdin.flush()
        returncode = process.wait()
        if returncode:
            raise OSError(returncode)

Вот моя функция декомпрессии / дешифрования

    def sevenZipDecompressDecryptFileFolder(self, file, destinationPath=None, password=None):
        try:
            if not os.path.exists(file):
                self.CELogger.error(f"The file ({file}) does not exist for encryption")
                return False

            theFilepath = pathlib.Path(file)
            theFilesuffix = theFilepath.suffix
            theFilename = theFilepath.stem

            if theFilesuffix != '.7z':
                self.CELogger.error(f"The file ({file}) does not have the .7z extension")
                return False
            if destinationPath is None:
                parentFolders = str(theFilepath.parent)
                decryptedFilepath = os.path.join(parentFolders)
            else:
                if not os.path.exists(destinationPath):
                    try:
                        os.makedirs(destinationPath)
                    except FileExistsError:
                        pass
                decryptedFilepath = destinationPath

            sevenZipExecutablePath = self.getSevenZipExecutablePath()
            if sevenZipExecutablePath is False:
                self.CELogger.error("Unable to obtain the seven zip executable path")
                return False

            if password is None:
                CMD = [sevenZipExecutablePath, 'x','-r', '-y', file,"-o"+decryptedFilepath]
                executeResult = self.execute(CMD)
            else:
                CMD = [sevenZipExecutablePath, 'x', '-r', '-y', file, '-p',  "-o"+decryptedFilepath]
                stringCMD = f'"{sevenZipExecutablePath}" x -r -y "{file}" -p{password} -o"{decryptedFilepath}"'
                #os.system(stringCMD)
                input = (password + "\r\n").encode("ascii")
                executeResult = self.execute(CMD, input)

            return decryptedFilepath
        except:
            self.CELogger.error(f"A problem occurred while attempting to decrypt the file ({file})")
            tb = traceback.format_exc()
            self.CELogger.exception(tb)
            return False

Моя программа сжатия / шифрования использует тот же подход и выполняет функцию и работает без проблем.

    def sevenZipCompressFileFolder(self, thePath,password=None,destinationDirectory=None,compressionLevel=9,multithreadedCompression="off"):
        try:
            if not os.path.exists(thePath):
                self.CELogger.error(f"Could not compress the file/folder at the path ({thePath}). Does not exist")
                return False
            pathlibPath = pathlib.Path(thePath)
            thePathname = pathlibPath.stem
            if destinationDirectory is None:
                destinationDirectory = str(pathlibPath.parent)
            else:
                if not os.path.exists(destinationDirectory):
                    try:
                        os.makedirs(destinationDirectory)
                    except FileExistsError:
                        pass

            destinationFilepath = os.path.join(destinationDirectory,thePathname+'.7z')
            sevenZipExecutablePath = self.getSevenZipExecutablePath()
            mxEntry = f"-mx={compressionLevel}"
            mmtEntry = f"-mmt={multithreadedCompression}"
            if password is None:
                CMD = [sevenZipExecutablePath, "a", "-t7z", mxEntry, mmtEntry, "-mf=on", "-mhc=on", "-mhe=on", "-ms=on","-m0=LZMA2", "-r", "-y", "-aoa", "-ssw", destinationFilepath, thePath]
                executeResult = self.execute(CMD)
            else:
                CMD = [sevenZipExecutablePath, "a", "-t7z",'-p', mxEntry, mmtEntry, "-mf=on", "-mhc=on", "-mhe=on", "-ms=on","-m0=LZMA2", "-r", "-y", "-aoa", "-ssw", destinationFilepath, thePath]
                input = (password + "\r\n").encode("ascii")
                executeResult = self.execute(CMD, input)
        except:
            self.CELogger.error("An error has occurred while attempting to compress file with seven zip")
            tb = traceback.format_exc()
            self.CELogger.exception(tb)
            return False

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

Более того, вы можете заметить, что у меня закомментирован вызов os.system. Это связано с тем, что я попытался использовать команду stringCMD с предварительно введенным паролем, не передавая ее во входной поток (менее безопасная версия). Это также не работает в Python и os.system. Однако, если я копирую переменную stringCMD и вручную открываю окно CMD, вставляю и запускаю, он прекрасно ее расшифровывает.

Что я делаю не так? Я пробовал много разных вещей, но не могу заставить их работать.

Обратите внимание, что ошибки относятся к python и этим функциям. Тривиальные ошибки, такие как невозможность перезаписать файлы, неправильный пароль и т. Д. c. не являются фактором, и такие случаи уже проверены.

Вам также может быть интересно отметить, что я могу распаковать и расшифровать файл с помощью стандартной утилиты 7 zip (щелкните файл правой кнопкой мыши и выберите извлечь архив, введите пароль et c.)

Спасибо

* ИЗМЕНИТЬ Это тоже проблема, когда я пытаюсь «обновить» сжатый архив. Как и при распаковке, мне нужно указать пароль. В этой ситуации также не работает передача пароля и команды через функцию выполнения. Итак, похоже, нет проблем с созданием архива с паролем. Однако проблема заключается в последующем изменении файла с тем же паролем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...