Search code examples
pythonpython-3.xaespython-zipfile

zipfile: Adding files to encrypted zip


I have an encrypted ZIP file and for some reason, any password I feed it doesn't seem to matter as it can add files to the archive regardless. I checked for any ignored exceptions or anything, but nothing seems to be fairly obvious.

I posted the minimalist code below:

import zipfile

z = zipfile.ZipFile('test.zip', 'a') #Set zipfile object
zipPass = str(input("Please enter the zip password: "))
zipPass = bytes(zipPass, encoding='utf-8')
z.setpassword(zipPass) #Set password
z.write("test.txt")

I am not sure what I am missing here, but I was looking around for anything in zipfile that can handle encrypted zipfiles and add files into them using the password, as the only thing I have is the ``z.setpassword()` function that seems to not work here.

TL;DR: z.write() doesn't throw an exception and neither does z.setpassword() or anything zipfile related when fed the incorrect password, and willingly adds files no matter what. I was expecting to get BadPasswordForFile.

Is there any way to do this?


Solution

  • After all of the lovely replies, I did find a workaround for this just in case someone needs the answer!

    I did first retry the z.testzip() and it does actually catch the bad passwords, but after seeing that it wasn't reliable (apparently hash collisions that allow for bad passwords to somehow match a small hash), I decided to use the password, extract the first file it sees in the archive, and then extract it. If it works, remove the extracted file, and if it doesn't, no harm done.

    Code works as below:

    try:
        z = zipfile.ZipFile(fileName, 'a') #Set zipfile object
        zipPass = bytes(zipPass, encoding='utf-8') #Str to Bytes
        z.setpassword(zipPass) #Set password
        filesInArray = z.namelist() #Get all files
        testfile = filesInArray[0] #First archive in list
        z.extract(testfile, pwd=zipPass) #Extract first file
        os.remove(testfile) #remove file if successfully extracted
    except Exception as e:
        print("Exception occurred: ",repr(e))
        return None #Return to mainGUI - this exits the function without further processing
    

    Thank you guys for the comments and answers!