Introduction
- To compress a file with encryption, set the password with the CZipArchive::SetPassword() method before compression. You will need to set
the same password with this method before decompressing this file later. You can
set different passwords for different files.
- To clear the password, call the CZipArchive::SetPassword()
method without arguments or with an empty string as an argument.
- You should avoid using characters other than ASCII in the password string. There
may be problems with extracting such an archive on a system with a different code
page. If you need to, you can control the code page when settings a password with
the CZipArchive::SetPassword() method.
- Choose the encryption method with the CZipArchive::SetEncryptionMethod()
method when compressing. The compression method is set by default to CZipCryptograph::encStandard. The encryption method used to compress
a file will be automatically detected while decompressing. You can set different
encryption methods for different files.
- You will need both the password and the encryption method set for the file to be
encrypted. Check the return value of the CZipArchive::WillEncryptNextFile()
method to find out, if the next file you add to the archive will be encrypted.
- To find out, if a file inside an archive is encrypted, call the CZipFileHeader::IsEncrypted() method.
- You can also encrypt data when getting files from other archives. See Compressing Data for information how to get files from other archives.
Encrypting Existing Files in an Archive
To encrypt existing files in an archive, use one of the following methods:
- These methods will not affect files that are already encrypted.
- The files will not be encrypted, if the archive is segmented or if there is a file
opened for compression or extraction.
Callbacks Called
When encrypting existing files, the following callbacks are called:
Additional Considerations
- Aborting the encryption process while any of the above callbacks is called will
result most probably in a corrupted archive.
- To read more about using callback objects when performing multiple operations, see
Progress Notifications: Using Callback Objects.
Standard Zip Encryption
The standard zip encryption method (
CZipCryptograph::encStandard)
is considered weak and should be only used with low security requirements or for
preserving compatibility with applications that do not support
the strong encryption.
Sample Code
LPCTSTR zipFileName = _T("C:\\Temp\\test.zip");
LPCTSTR password = _T("secret");
CZipArchive zip;
zip.Open(zipFileName, CZipArchive::zipCreate);
zip.SetPassword(password);
zip.AddNewFile(_T("C:\\Temp\\file1.dat"));
zip.SetPassword();
zip.AddNewFile(_T("C:\\Temp\\file2.dat"));
zip.Close();
zip.Open(zipFileName);
ASSERT(zip[0]->IsEncrypted());
ASSERT(!zip[1]->IsEncrypted());
zip.SetPassword(password);
zip.ExtractFile(0, _T("C:\\Temp"), false, _T("file1.ext"));
zip.ExtractFile(1, _T("C:\\Temp"), false, _T("file2.ext"));
zip.Close();
Strong AES Encryption Conforming to the WinZip Format
The ZipArchive Library supports AES encryption with key sizes
128-bit,
192-bit and
256-bit. The
format of AES encrypted data conforms to
the WinZip AES Encryption Specification. It is the preferred
way to ensure that your data is secure. The ZipArchive Library encrypts files the
way the WinZip does:
- If the file size is smaller than 20 bytes, AE-2 encryption format is used. In this
case, CRC value is not written in the archive to avoid discovery of the encrypted
file contents in some cases.
- For larger files, AE-1 format is used to provide an extra integrity check.
Enabling AES Encryption in the ZipArchive Library
To use the AES encryption, you need to make sure that
_ZIP_AES
is defined in the
_features.h file. Rebuild the ZipArchive
Library and your application, if you modify this definition. You may choose to keep
the encryption disabled, if you don't use it, to keep the size of the compiled library
smaller.
Encrypting Archives with AES
You need to choose the encryption method with the
CZipArchive::SetEncryptionMethod()
using one of the
CZipCryptograph::EncryptionMethod
values.
Sample Code
LPCTSTR zipFileName = _T("C:\\Temp\\test.zip");
LPCTSTR password = _T("secret");
CZipArchive zip;
zip.Open(zipFileName, CZipArchive::zipCreate);
zip.SetPassword(password);
zip.SetEncryptionMethod(CZipCryptograph::encWinZipAes256);
zip.AddNewFile(_T("C:\\Temp\\file1.dat"));
zip.SetEncryptionMethod(CZipCryptograph::encStandard);
zip.AddNewFile(_T("C:\\Temp\\file2.dat"));
zip.Close();
zip.Open(zipFileName);
ASSERT(zip[0]->IsEncrypted());
ASSERT(zip[1]->IsEncrypted());
zip.SetPassword(password);
zip.ExtractFile(0, _T("C:\\Temp"), false, _T("file1.ext"));
zip.ExtractFile(1, _T("C:\\Temp"), false, _T("file2.ext"));
zip.Close();
Special Considerations
- If you use AES encryption in the ZipArchive Library in multiple threads, you should
define _ZIP_USE_LOCKING in the _features.h
file (it is not defined by default). This will ensure the proper locking mechanism
when generating AES keys.
- If all the conditions below take place:
then you need to set CZipFileHeader::m_uLocalUncomprSize
to the size of the data you want to compress (uncompressed data size) before passing
the CZipFileHeader object to the CZipArchive::OpenNewFile() method. This will cause the uncompressed size
to be written in the local header. Otherwise WinZip 9.0 will complain about the
invalid decompressed size when extracting the file. It is not considered to be a
valid behavior, because in this case the data descriptor is written and uncompressed
data size written in the local header should be discarded. The WinZip 11.0 and newer
does not expose this issue.
Checking Password Validity
The password itself is not stored inside of an archive. A preliminary check is performed
when opening a file in an archive for extraction (e.g. with the
CZipArchive::OpenFile() method). The ZipArchive Library throws
CZipException::badPassword, if this preliminary check fails. However,
this is not reliable enough to detect all cases of an invalid password.
The final check is performed when a file is completely extracted. A file's data checksum
is then verified (but only if the consistency check
CZipArchive::checkCRC
was not disabled with the
CZipArchive::SetIgnoredConsistencyChecks()
method). If it fails, an exception with the code
CZipException::badCrc
is thrown. At this point it is not possible to distinguish whether the bad checksum
was caused by an invalid password or a corrupted archive.
See Also API Links