Что такое спецификация надежного шифрования Zip / получение ключа SecureZip?
В спецификации ZIP (PK) на https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT, в частности в разделе Спецификация надежного шифрования (SES), есть строка о получении ключа из пароля:
MasterSessionKey = DeriveKey(SHA1(Password))
Что
DeriveKey
?
(В документации WinZip AES по адресу https://www.winzip.com/en/support/aes-encryption/ они используют PBKDF2 с 1000 итерациями. Я не вижу аналогичного объяснения в APPNOTE)
2 ответа
PKWARE
реализовано стойкое шифрование в версии 5, но не предоставлен алгоритм кодирования/декодирования (Метод для строго зашифрованных файлов .ZIP - патент США 2020/0250329 A1). В этом алгоритме шифрование AES было реализовано как его часть. Вы можете определить это сильным шифрованием (бит 6) = да во флаге общего назначения .
После этогоWinZip
не мог использовать этот алгоритм, поэтому он изобрел другой. Вы можете определить это сильным шифрованием (бит 6) = no во флаге общего назначения и AesExtraFieldRecord с подписью 0x990.
Как видите, есть два способа зашифроватьzip
файл. Все программное обеспечение с открытым исходным кодом использует второй. Первый доступен только через PKWARE SecureZIP.
Вы можете найти пример этого алгоритма в (7zip) Strong.cpp:35 . Вjava
это должно выглядеть так:
public static byte[] getMasterKey(String password) {
byte[] data = password.getBytes(StandardCharsets.UTF_8);
byte[] sha1 = DigestUtils.sha1(data);
return DeriveKey(sha1);
}
private static byte[] DeriveKey(byte[] digest) {
byte[] buf = new byte[kDigestSize * 2]; // kDigestSize = 20
DeriveKey2(digest, (byte)0x36, buf, 0);
DeriveKey2(digest, (byte)0x5C, buf, kDigestSize);
return Arrays.copyOfRange(buf, 0, 32);
}
private static void DeriveKey2(byte[] digest, byte c, byte[] dest, int offs) {
byte[] buf = new byte[64];
Arrays.fill(buf, c);
for (int i = 0; i < kDigestSize; i++)
buf[i] ^= digest[i];
byte[] sha1 = DigestUtils.sha1(buf);
System.arraycopy(sha1, 0, dest, offs, sha1.length);
}
Демо:
String password = "JohnDoe";
byte[] masterKey = getMasterKey(password);
Следующий абзац «определяет» его
7.2.5.3 Имена функций и требования к параметрам будут зависеть от выбранного набора криптографических инструментов. Можно использовать практически любой инструментарий, поддерживающий эталонные реализации для каждого алгоритма. Известно, что библиотеки RSA BSAFE(r), OpenSSL и MicrosoftCryptoAPI работают хорошо.
Я думаю, вам решать, какой из алгоритмов шифрования вы хотите использовать, и исходить из этого.