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