JEP 510: Key Derivation Function API
Key Derivation Function API
| Ответственный | Kevin Driver |
| Тип | Feature |
| Область | SE |
| Статус | Closed / Delivered |
| Выпуск | 25 |
| Компонент | security-libs / javax.crypto |
| Обсуждение | security dash dev at openjdk dot org |
| Трудоёмкость | XS |
| Длительность | XS |
| Связан с | JEP 478: Key Derivation Function API (Preview) |
| Рецензенты | Sean Mullan |
| Одобрен | Sean Mullan |
| Создан | 2025/03/31 14:08 |
| Обновлён | 2026/02/05 19:50 |
| Задача | 8353275 |
Аннотация
Добавить API для функций выработки ключей (Key Derivation Functions, KDF) — криптографических алгоритмов, которые вырабатывают дополнительные ключи из секретного ключа и других данных.
История
Мы предложили KDF API в статусе Preview (предварительная версия) в JEP 478, и он вошёл в JDK 24. Здесь мы предлагаем сделать API окончательным в JDK 25 без изменений.
Цели
-
Дать приложениям возможность использовать алгоритмы KDF, такие как HMAC-based Extract-and-Expand Key Derivation Function (HKDF, RFC 5869) и Argon2 (RFC 9106).
-
Дать возможность использовать KDF в реализациях механизма инкапсуляции ключей (Key Encapsulation Mechanism, KEM, JEP 452), таких как ML-KEM, в протоколах более высокого уровня, таких как Hybrid Key Exchange in TLS 1.3, и в криптографических схемах, таких как Hybrid Public Key Encryption (HPKE, RFC 9180).
-
Дать возможность создать в JDK реализацию HKDF на основе PKCS#11.
-
Дать возможность реализации Hybrid Public Key Encryption (HPKE) в JDK использовать KDF при настройке расписания ключей (key schedule) и экспорте секретов.
-
Дать возможность переработать реализации TLS 1.3 и DHKEM в JDK так, чтобы они использовали KDF API вместо внутренней реализации HKDF.
-
Позволить провайдерам безопасности реализовывать алгоритмы KDF как на Java, так и в нативном коде.
-
Включить реализацию HKDF и добавить дополнительные API, специфичные для HKDF.
Что не является целью
- Цель не состоит в том, чтобы сделать существующие реализации функций выработки ключей на основе пароля (Password-Based Key Derivation Functions) PBKDF1 и PBKDF2 доступными через новый KDF API. Эти реализации по-прежнему будут доступны через существующий API
SecretKeyFactory.
Мотивация
Функции выработки ключей (KDF) используют криптографические входные данные, такие как исходный ключевой материал, значение соли (salt) и псевдослучайная функция, чтобы создать новый криптографически стойкий ключевой материал. KDF часто применяют для создания криптографических данных, из которых можно получить несколько ключей. KDF позволяет создавать ключи безопасно и при этом воспроизводимо для двух сторон, которые обе знают входные данные.
Выработка ключей похожа на хэширование паролей. KDF использует хэш с ключом (keyed hash) вместе с дополнительной энтропией из других своих входных данных, чтобы либо извлечь новый ключевой материал, либо безопасно расширить значения в более длинный поток ключевого материала.
С появлением квантовых вычислений классические криптографические алгоритмы будут всё более уязвимы для практических атак. Поэтому платформе Java крайне важно поддерживать постквантовую криптографию (Post-Quantum Cryptography, PQC), устойчивую к таким атакам. Со временем мы намерены добиться этого, поддержав Hybrid Public Key Encryption (HPKE), что обеспечивает плавный переход на алгоритмы шифрования, стойкие к квантовым атакам. KEM API (JEP 452), вошедший в JDK 21, — один из строительных блоков HPKE и был нашим первым шагом к HPKE и готовности к постквантовой криптографии; предлагаемый здесь KDF API — ещё один строительный блок HPKE, и он станет вторым шагом.
Расширяемость, которую даёт добавление KDF API, принесёт и другие преимущества. Стандарт PKCS#11 для криптографических аппаратных устройств уже много лет описывает поддержку KDF. Если сделать эту технологию доступной через API javax.crypto, это пойдёт на пользу приложениям и библиотекам, которые работают с такими устройствами. Кроме того, разработчики сторонних криптопровайдеров могут предлагать собственные реализации KDF, в частности прошедшие проверку тестированием и затем сертифицированные National Institute of Standards and Technology.
Наконец, крайне важно, чтобы платформа Java лучше поддерживала на уровне API функции KDF для хэширования паролей, более совершенные, чем PBKDF1 и PBKDF2, например Argon2. Ни один из существующих криптографических API платформы Java сейчас не позволяет естественным образом представить KDF (см. ниже). Разработчики сторонних провайдеров безопасности уже заявили о потребности в стандартном KDF API.
Описание
У функции выработки ключей две основные операции:
-
Создание и инициализация — создаёт KDF и инициализирует её соответствующими параметрами, и
-
Выработка — принимает ключевой материал и другие необязательные входные данные, а также параметры, описывающие результат, и затем вырабатывает производный ключ или данные.
Для представления функций выработки ключей мы вводим новый класс javax.crypto.KDF.
Создание и инициализация
Класс KDF предоставляет обычный набор методов getInstance с обычными комбинациями параметров, включая необязательные KDFParameters и имена криптопровайдеров. Методы getInstance одновременно создают экземпляр KDF и инициализируют его алгоритм.
Алгоритму HKDF — единственной KDF, которую мы сейчас собираемся включить, — объект KDFParameters не нужен. Однако другим алгоритмам, например SHAKE, он может понадобиться.
Выработка
В классе KDF определены два метода выработки ключей:
-
deriveKey(String alg, AlgorithmParameterSpec spec) создаёт объектSecretKey, используя указанный алгоритм и в соответствии с указанными параметрами. -
deriveData(AlgorithmParameterSpec spec)возвращает массив байтов, который можно использовать как источник энтропии или если ключевой материал нужен именно в таком виде.
Мы используем пустой интерфейс AlgorithmParameterSpec, потому что разные алгоритмы KDF принимают разные параметры. В реализации KDF следует определить один или несколько подклассов AlgorithmParameterSpec для описания её параметров.
Для входящей в состав реализации HKDF мы предоставляем три таких подкласса, каждый из которых представляет входные данные для отдельного режима работы:
Объемлющий интерфейс HKDFParameterSpec определяет статические фабричные методы для создания экземпляров этих трёх классов. Он также определяет класс-построитель HKDFParameterSpec.Builder для сборки ключевого материала для операций извлечения.
Пример
// Create a KDF object for the specified algorithm
KDF hkdf = KDF.getInstance("HKDF-SHA256");
// Create an ExtractExpand parameter specification
AlgorithmParameterSpec params =
HKDFParameterSpec.ofExtract()
.addIKM(initialKeyMaterial)
.addSalt(salt).thenExpand(info, 32);
// Derive a 32-byte AES key
SecretKey key = hkdf.deriveKey("AES", params);
// Additional deriveKey calls can be made with the same KDF object
Реализация провайдеров KDF
Реализация KDF должна расширять абстрактный класс javax.crypto.KDFSpi.
Некоторые алгоритмы KDF вырабатывают несколько криптографических ключей за одну операцию выработки. Если вы реализуете такой алгоритм, мы рекомендуем либо предоставить подкласс SecretKey с методами, дающими доступ к каждому ключу, либо возвращать все ключи в одном массиве байтов и документировать, как их разделить.
Дальнейшая работа
- Реализовать Argon2 — со временем мы намерены реализовать KDF для хэширования паролей Argon2.
Альтернативы
-
Использовать существующие API — мы рассматривали возможность представить KDF с помощью существующих API
KeyGeneratorиSecretKeyFactory. Более ранние алгоритмы выработки ключей, такие как TLS-PRF, PBKDF1 и PBKDF2, удалось вписать в эти API, но в целом эти API плохо подходят для KDF.-
KeyGeneratorпостроен вокруг внесения энтропии через объектSecureRandom, чтобы создать недетерминированный ключ из набора входных данных. KDF, напротив, поддерживают независимую выработку одного и того же ключевого материала двумя отдельными сторонами. -
SecretKeyFactoryрассчитан на создание одного ключа. Хотя есть сценарии, в которых KDF может использоваться таким образом, KDF также должны поддерживать последовательную детерминированную выработку из ключевого потока.
-
-
Сделать PBKDF2 доступным через новый API
KDF— PBKDF2 быстро вытесняется более стойкими алгоритмами, такими как Argon2. Разработчики, которые уже используют PBKDF2, скорее всего, продолжат использовать его через APISecretKeyFactory, а не станут переделывать существующий код под APIKDF. Поэтому делать PBKDF2 доступным через новый API сейчас нет оснований, но мы можем сделать это позже, если возникнет настоятельная потребность.
Тестирование
Мы добавим тесты с известными ответами (known-answer tests, KAT) из RFC 5869, если они доступны, а также тесты обработки исключений и регрессионное тестирование SSL/TLS.