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
The AES encryption is enabled by default in the ZipArchive Library. You may choose to disable
it if you don't use it, to keep the size of the compiled library smaller.
With CMake: Control AES encryption using the ZIP_ENABLE_AES option:
- -DZIP_ENABLE_AES=ON - Enable AES encryption (default)
- -DZIP_ENABLE_AES=OFF - Disable AES encryption
Without CMake: Make sure _ZIP_AES
is defined and set to 1 in the _features.h file. Rebuild the ZipArchive
Library and your application if you modify this definition.
Hardware AES Acceleration
The ZipArchive Library supports hardware-accelerated AES encryption/decryption using CPU-specific instructions. This provides significant performance improvements (8-14x faster) when available:
- Intel/AMD processors: AES-NI instruction set (Westmere/2010 and newer)
- ARM processors: ARMv8 Crypto Extensions (all Apple Silicon, most modern ARM64 CPUs)
Hardware acceleration is automatically detected at runtime and used when available, with automatic fallback to software implementation on older CPUs. This feature is enabled by default.
With CMake: Control hardware AES acceleration using the ZIP_USE_HWAES option:
- -DZIP_USE_HWAES=ON - Enable hardware AES acceleration with runtime detection (default)
- -DZIP_USE_HWAES=OFF - Use software-only AES implementation
Without CMake: Define _ZIP_USE_HWAES and set it to 1 in the _features.h file to enable hardware acceleration (default), or set to 0 to disable it.
Hardware CRC-32 Acceleration
The ZipArchive Library also supports hardware-accelerated CRC-32 computation using CPU-specific instructions. This provides performance improvements for standard zip CRC encryption or checksum calculations:
- Intel/AMD processors: PCLMULQDQ instruction with SSE4.1 (Westmere/2010 and newer)
- ARM processors: ARMv8 CRC32 instructions (available on all Apple Silicon and most ARMv8.0+ CPUs)
Hardware acceleration is automatically detected at runtime and used when available, with automatic fallback to software implementation on older CPUs. This feature is enabled by default.
With CMake: Control hardware CRC-32 acceleration using the ZIP_USE_HWCRC option:
- -DZIP_USE_HWCRC=ON - Enable hardware CRC-32 acceleration with runtime detection (default)
- -DZIP_USE_HWCRC=OFF - Use software-only CRC-32 implementation
Without CMake: Define _ZIP_USE_HWCRC and set it to 1 in the _features.h file to enable hardware acceleration (default), or set to 0 to disable it.
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 enable thread safety:
- With CMake: Use -DZIP_ENABLE_USE_LOCKING=ON (disabled by default). This will ensure the proper locking mechanism when generating AES keys.
- Without CMake: Define _ZIP_USE_LOCKING and set it to
1 in the _features.h file (default is 0).
- 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