I need to create a temporary zip file to store files. That ZIP file needs to be encrypted, so zipfile won't do the trick here. The file will be further encrypted (the ZIP will be encrypted again into another file), so zipping the file is used as a way of reducing its size for faster internet transmission as well as the first layer of encryption. Here's what I've got so far:
import getpass
import tempfile
import pyminizip
def ZipFunction():
#This zips the file and encrypts it with a password
filename = input('Enter the file name: ')
passkey = getpass.getpass(prompt='Enter the password for the file: ')
passkey2 = getpass.getpass(prompt='Confirm the password: ')
if passkey != passkey2:
print('The passwords must be the same! Please restart the process.')
exit()
else:
#Here's where I need help
with tempfile.TemporaryFile() as tmp:
with pyminizip.compress(filename,None,tmp,passkey,9) as archive:
zipstring = archive.readlines()
#From here on the zipstring var is encrypted and creates the "further encrypted"
#file. From here on the script works normally
The error returned is ValueError: expected arguments are compress(src, srcpath, dst, pass, level).
I'd be willing to change pyminizip to another tool that can create encrypted zip files. This "dual encryption layer" is a customer demand, and although I don't really think it's necessary, I don't have the authority to scrap it from the project.
I'm not used to dealing with Temporary Files. What am I doing wrong here?
With the tempfile-module temporary files can be created which are automatically deleted when closing or leaving a with-block. With the pyminizip-module encrypted zip-files can be obtained.
pyminizip.compress expects as third parameter the path where the generated zip-file should be saved. If a file is already there, an attempt is made to overwrite it. The current code uses the reference to the tempfile (tmp), which leads to the observed error message:
ValueError: expected arguments are compress(src, srcpath, dst, pass, level)
The direct cause of the error is that the reference itself and not its file name is used, i.e. to avoid the error, tmp.name should actually be used instead of tmp. However, if this is changed, a different error message is generated, namely
OSError: error in closing <path to temo file> (-102)
This is because the pyminizip-module tries to delete the tempfile while it is still open. If the tempfile were closed before, it would be overwritten without error message. However, this would only create a normal file and not a tempfile, i.e. the file wouldn't be deleted automatically when closing or leaving the with-block.
Thus, it is not possible to create temporary, encrypted zip-files with the tempfile- and pyminizip-module in this way. However, the tempfile-module allows the creation of temporary files as well as temporary directories. Like temporary files, temporary directories are deleted when leaving a with-block. If a temporary directory is deleted, the files contained therein are also deleted. Therefore an alternative would be common, encrypted zip-files (created with the pyminizip-module), which are stored in a temporary folder (created with the tempfile-module):
...
with tempfile.TemporaryDirectory() as tdir:
sourceFile = <path to file to be zipped>
destinationFile = "destFile.zip"
password = "whatever"
compression_level = 9 # 1-9
pyminizip.compress(sourceFile, None, tdir + "\\" + destinationFile, password, compression_level)
# inside with-block: temp-directory and contained encrypted zip-files exist
...
# outside with-block: temp-directory and contained encrypted zip-files deleted
...
If the with-block is left, the temporary directory is deleted along with any encrypted zip files it contains.
By the way: pyminizip.compress doesn't support a with-statement. This would cause the error message: AttributeError: __enter__. In the current code you can't see this error message, because the posted error message is triggered before.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With