Reputation: 97
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
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
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
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
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