Что такое спецификация надежного шифрования 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 работают хорошо.

Я думаю, вам решать, какой из алгоритмов шифрования вы хотите использовать, и исходить из этого.

Другие вопросы по тегам