4

我正在使用ZipArchive在 iOS 应用程序中提取 zip 文件,但我想在打开文件之前知道它是否受密码保护,以便我可以将密码传递给 UnZipOpenFile 函数。

4

4 回答 4

4

zip 文件的密码不记录在标题中,它记录在 zip 中的单个文件条目中

所以你需要检查 zip 中的所有文件

将此功能添加到 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;
}
于 2012-12-18T16:57:00.390 回答
3

实际上,我在 zipArchive 中找不到检测文件是否已加密的功能,因此我检查了文件头以检查它是否受密码保护,如以下链接所述:

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;
    }
}

谢谢大家

于 2012-06-11T10:04:46.880 回答
2

我自己没有使用过 ZipArchive,但是通过查看代码,可以首先使用UnzipOpenFile没有密码参数的变体并尝试调用UnzipFileTo. 如果失败,您重新打开,但输入密码并UnzipFileTo再次调用。这样做的问题是您将无法区分无效的 zip 文件和使用无效的密码。

如果您真的需要知道文件是否已加密,您可以自己添加功能(未经测试的代码):

将此添加到unzip.cminizip 中:

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

这要unzip.h

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

这要ZipArchive.mm

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

这要ZipArchive.h

- (BOOL)ZipIsEncrypted;

并在调用后使用UnzipFileTo

于 2012-06-07T16:13:42.397 回答
1

我正在解压缩超过 50mb 的加密文件,所以在 NSData 中加载完整文件对我来说是个问题。所以修改了答案,我用了这个:

-(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;
    }

}
于 2014-03-25T11:29:46.560 回答