ZipArchiveを使用してiOSアプリケーションでzipファイルを抽出していますが、ファイルを開く前に、パスワードが保護されているかどうかを確認して、UnZipOpenFile関数にパスワードを渡すことができるようにします。
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;
}
実際、ファイルが暗号化されているかどうかを検出する関数が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;
}
}
全てに感謝
私自身はZipArchiveを使用していませんが、コードを見ると、最初UnzipOpenFile
にパスワード引数なしでバリアントを使用して、を呼び出そうとすることが可能UnzipFileTo
です。失敗した場合は、パスワードを使用して再度開き、UnzipFileTo
もう一度呼び出します。これに伴う問題は、無効なzipファイルと無効なパスワードの使用を区別できないことです。
ファイルが暗号化されているかどうかを本当に知る必要がある場合は、機能的に自分で追加することができます(テストされていないコード):
これをunzip.c
minizipに追加します。
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
ください。
私は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;
}
}