Eman.H
Eman.H

Reputation: 97

How to check if a zip file is password protected in IOS?

I am using ZipArchive to extract zip files in an iOS application, but I want to know before openning the file if it's password protected or not so that I can pass the password to the UnZipOpenFile function.

Upvotes: 4

Views: 2735

Answers (4)

IPaPa
IPaPa

Reputation: 468

password of a zip file is not record in header it is recorded in individual file entries in zip

so you need to check all files in zip

add this function to ZipArchive

-(BOOL) UnzipIsEncrypted {

    int ret = unzGoToFirstFile( _unzFile );
    if (ret == UNZ_OK) {
        do {
            ret = unzOpenCurrentFile( _unzFile );
            if( ret!=UNZ_OK ) {
                return NO;
            }
            unz_file_info   fileInfo ={0};
            ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
            if (ret!= UNZ_OK) {
                return NO;
            }
            else if((fileInfo.flag & 1) == 1) {
                return YES;
            }

            unzCloseCurrentFile( _unzFile );
            ret = unzGoToNextFile( _unzFile );
        } while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE );

    }

    return NO;
}

Upvotes: 4

bhavesh
bhavesh

Reputation: 109

i was unzipping more than 50mb Encrypted file so load full file in NSData was problem for me. so modified answer and i used this:

-(BOOL) IsEncrypted:(NSString*)path

{

    NSInteger chunkSize = 1024     //Read 1KB chunks.
    NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
    NSData *fileData = [handle readDataOfLength:chunkSize];
    NSData* generalBitFlag = [fileData subdataWithRange:NSMakeRange(6, 2)];
    NSString* genralBitFlgStr = [generalBitFlag description];


    if ([genralBitFlgStr characterAtIndex:2]!='0')
    {
        return true;
    }
    else
    {
        return false;
    }

}

Upvotes: 1

Mattias Wadman
Mattias Wadman

Reputation: 11425

I haven't used ZipArchive myself but by looking at the code it seams possible to first use the UnzipOpenFile variant without password argument and try to call UnzipFileTo. If it fails you reopen but with a password and call UnzipFileTo again. The problem with this is that you will not be able to distinguish between an invalid zip file and using a invalid password.

If you really need to know if the file is encrypted you could probably add the functionally yourself (untested code):

Add this to unzip.c in minizip:

extern int ZEXPORT unzIsEncrypted (file)
    unzFile file;
{
   return ((unz_s*)file)->encrypted;
}

This to unzip.h:

extern int ZEXPORT unzIsEncrypted OF((unzFile file));

This to ZipArchive.mm:

- (BOOL)ZipIsEncrypted {
    return unzIsEncrypted(_unzFile);
}

This to ZipArchive.h:

- (BOOL)ZipIsEncrypted;

And use it after calling UnzipFileTo.

Upvotes: 2

Eman.H
Eman.H

Reputation: 97

Acctually i couldn't find function in zipArchive that detects if the file is encrypted so i checked the file header to check if it's password protected or not as stated in the following link:

http://secureartisan.wordpress.com/2008/11/04/analysis-of-encrypted-zip-files/

-(BOOL) IsEncrypted:(NSString*)path
{
    NSData* fileData = [NSData dataWithContentsOfFile:path];
    NSData* generalBitFlag = [fileData subdataWithRange:NSMakeRange(6, 2)];
    NSString* genralBitFlgStr = [generalBitFlag description];

    if ([genralBitFlgStr characterAtIndex:2]!='0')
    {
        return true;
    }
    else
    {
        return false;
    }
}

Thanks for all

Upvotes: 3

Related Questions