慕婉清6462132
我终于能够使用 Anupam Chaplot 建议的名为“pyzipper”的库来完成对整个目录(包括所有子文件夹结构和文件)的加密。这是解决方案:def zip_folderPyzipper(folder_path, output_path): """Zip the contents of an entire folder (with that folder included in the archive). Empty subfolders will be included in the archive as well. """ parent_folder = os.path.dirname(folder_path) # Retrieve the paths of the folder contents. contents = os.walk(folder_path) try: zip_file = pyzipper.AESZipFile('new_test.zip','w',compression=pyzipper.ZIP_DEFLATED,encryption=pyzipper.WZ_AES) zip_file.pwd=b'PASSWORD' for root, folders, files in contents: # Include all subfolders, including empty ones. for folder_name in folders: absolute_path = os.path.join(root, folder_name) relative_path = absolute_path.replace(parent_folder + '\\', '') print ("Adding '%s' to archive." % absolute_path) zip_file.write(absolute_path, relative_path) for file_name in files: absolute_path = os.path.join(root, file_name) relative_path = absolute_path.replace(parent_folder + '\\', '') print ("Adding '%s' to archive." % absolute_path) zip_file.write(absolute_path, relative_path) print ("'%s' created successfully." % output_path) except IOError as message: print (message) sys.exit(1) except OSError as message: print(message) sys.exit(1) except zipfile.BadZipfile as message: print (message) sys.exit(1) finally: zip_file.close()由于我是 python 新手,我无法详细解释代码。以下是参考资料:https://pypi.org/project/pyzipper/https://www.calazan.com/how-to-zip-an-entire-directory-with-python/在 windows 中提取生成的 ZIP 文件:右键->解压(加密)如果直接点击Extract All选项,则会报错
月关宝盒
试试这个:首先请在这里检查pynzip。之后尝试一下。import pyminizip as pyzipcompression = 8pyzip.compress("test.txt", "test.zip", "Pswrd", compression)这是如何复制所有目录及其子目录及其文件,然后将其压缩并加密一个zip,使用密码并且不需要关联的备份文件,这里我们将看到如何授权一个mac地址来执行解密。因此,由您决定更改或改进脚本。但基本要素工作得很好。经过大量的研究、测试和思考,我创建了这个有效的解决方案我的设置:Python 3.8 64:Windows 7 64 上的位:位使用术语:第一步,我们需要导入加密模块检查是否支持或其他在这里https://cryptography.io/en/latest/installation/ 命令:pip install cryptography然后我们将使用这个模块产生的 fernet 对象 https://cryptography.io/en/latest/fernet/带密码 https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet和shutil: https ://docs.python.org/3/library/shutil.html 文件second.py:import osimport re, uuidimport stringimport shutilimport zlibfrom cryptography.fernet import Fernetfrom cryptography.hazmat.primitives import hashesfrom cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMACimport base64import zipfileclass zipy: def __init__(self, pathDir=None): """If pathDir optional is none, this script copy all directory in current execution.""" if pathDir != None: if os.path.isdir(pathDir): pathDir = pathDir.replace(os.sep, '/') if pathDir.endswith('/'): self.root = pathDir else: self.root = pathDir + '/' else: self.root = os.getcwd()+os.sep self.root = self.root.replace(os.sep, '/') else: self.root = os.getcwd()+os.sep self.root = self.root.replace(os.sep, '/') os.chdir(self.root) self.name = 'sauvegarde' self.dirSauvegarde = self.root+self.name self.dirSauvegarde = self.dirSauvegarde.replace(os.sep, '/') lectureDossier = os.listdir(self.root) print(lectureDossier) self.path_system = {} for element in lectureDossier: if os.path.isdir(element): if element != '__pycache__': self.path_system[element] = self.root + element + os.sep.replace(os.sep, '/') self.path_system[element] = self.path_system[element].replace(os.sep, '/') else: pass elif os.path.isfile(element): self.path_system[element] = self.root + element self.path_system[element] = self.path_system[element].replace(os.sep, '/') else: pass self.zipi = myZip(self.dirSauvegarde) def save(self): """sauvegarde le fichier""" self.createDir(self.dirSauvegarde) chemin_src = "" chemin_dist = "" for element in self.path_system: if element != self.dirSauvegarde: chemin_src = self.root+element chemin_dest = self.dirSauvegarde + os.sep + element chemin_dest = chemin_dest.replace(os.sep, '/') if os.path.isdir(chemin_src): self.copyDir(chemin_src, chemin_dest) else: self.copyFile(chemin_src, chemin_dest) self.zipi.zip(zip_exist=True) self.delDir(self.dirSauvegarde) def copyDir(self, src, dest): try: shutil.copytree(src, dest, dirs_exist_ok=True) except: pass def copyFile(self, src, dest): try: shutil.copyfile(src, dest) except: pass def createDir(self, dirPath): if os.path.isdir(dirPath): self.delDir(dirPath) else: pass os.makedirs(dirPath, exist_ok=True) def delDir(self, dir): if os.path.isdir(dir): if len(os.listdir(dir)) > 0: try: print('rmtree') shutil.rmtree(dir, ignore_errors=True) except: pass else: try: os.rmdir(dir) except: pass def decrypt(self): self.zipi.unzip() class myZip: def __init__(self, dir): self.pathDir = dir self.nom = os.path.basename(dir) self.pathZip = self.pathDir + '.zip' self.crypt = Encryptor() def zip(self, zip_exist=False): if zip_exist == False: pass else: if os.path.isfile(self.pathZip): try: os.remove(self.pathZip) except: pass shutil.make_archive(os.path.splitext(self.pathZip)[0], 'zip', self.pathDir) key = self.crypt.key_create() #TEST self.crypt.file_encrypt(key, self.pathZip, self.pathZip) self.crypt.key_write(self.pathZip, key) def unzip(self): #TEST if self.crypt.checkPass(self.pathZip): #print('ok adresse mac autoriser') key = self.crypt.key_load(self.pathZip) self.crypt.file_decrypt(key, self.pathZip, self.pathZip) else: print('pas ok adresse mac erroner')class Encryptor: def __init__(self): self.salto = None def key_create(self): password = self.getMac() password = bytes(password, encoding="utf-8") self.salto = os.urandom(16) print(self.salto) kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=self.salto, iterations=100, ) key = base64.urlsafe_b64encode(kdf.derive(password)) return key def key_write(self, pathZip, key): with zipfile.ZipFile(pathZip, 'a') as zip: zip.comment = key + bytes(' byMe ', encoding="utf-8") + self.salto def key_load(self, pathZip): stri = [] with zipfile.ZipFile(pathZip, 'a') as zip: stri = zip.comment.split(b' byMe ') print(stri[0]) print(stri[1]) key = stri[0] self.salto = stri[1] return key def checkPass(self, pathZip): key = base64.urlsafe_b64decode(self.key_load(pathZip)) salt = self.salto mdp = self.getMac() mdp = bytes(mdp, encoding="utf-8") kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100, ) retour = False try: kdf.verify(mdp, key) retour = True except: retour = False return retour def file_encrypt(self, key, original_file, encrypted_file): f = Fernet(key) with open(original_file, 'rb') as file: original = file.read() encrypted = f.encrypt(original) with open (encrypted_file, 'wb') as file: file.write(encrypted) def file_decrypt(self, key, encrypted_file, decrypted_file): f = Fernet(key) with open(encrypted_file, 'rb') as file: encrypted = file.read() decrypted = f.decrypt(encrypted) with open(decrypted_file, 'wb') as file: file.write(decrypted) def getMac(self): return "".join(re.findall('..', '%012x' % uuid.getnode()))像这样使用:文件:main.pyfrom second import zipy#If the argument is empty, the script will make a copy of the directory being executed, otherwise the script will work and output the zip in the place indicated in argument dd = zipy("E:/path")#or dd = zipy("E:/path/") or dd = zipy() if you give arg, give absolute path#Save the zip and encrypt it. Change second.py to directly give it a password as an argument dd.save()#decrypt zipdd.decrypt()