JEP 496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism
Механизм инкапсуляции ключей на основе модульных решёток, устойчивый к квантовым вычислениям
| Ответственный | Weijun Wang |
| Тип | Feature |
| Область | SE |
| Статус | Closed / Delivered |
| Выпуск | 24 |
| Компонент | security-libs / javax.crypto |
| Обсуждение | security dash dev at openjdk dot org |
| Трудоёмкость | M |
| Длительность | S |
| Рецензенты | Sean Mullan |
| Одобрен | Alan Bateman, Sean Mullan |
| Создан | 2024/08/26 18:33 |
| Обновлён | 2025/03/13 14:49 |
| Задача | 8339009 |
Аннотация
Повысить безопасность Java-приложений за счёт реализации устойчивого к квантовым вычислениям механизма инкапсуляции ключей на основе модульных решёток (Module-Lattice-Based Key-Encapsulation Mechanism, ML-KEM). Механизмы инкапсуляции ключей (KEM) служат для защиты симметричных ключей при передаче по незащищённым каналам связи с помощью криптографии с открытым ключом. ML-KEM разработан так, чтобы оставаться стойким к будущим атакам с использованием квантовых вычислений. Он стандартизирован Национальным институтом стандартов и технологий США (NIST) в FIPS 203.
Цели
- Предоставить реализации ML-KEM для API
KeyPairGenerator,KEMиKeyFactoryс поддержкой наборов параметров ML-KEM-512, ML-KEM-768 и ML-KEM-1024, стандартизированных в FIPS 203.
Что не является целью
-
Реализация алгоритма Kyber, на основе которого создан ML-KEM, не является целью. Эти два алгоритма несовместимы между собой.
-
Добавление поддержки ML-KEM в компоненты платформы Java, для которых ещё нет необходимых стандартов, не является целью. В частности, это относится к реализации протокола Transport Layer Security (TLS) в пакете
javax.net.ssl. Мы добавим такую поддержку, когда соответствующие стандарты появятся.
Мотивация
Область квантовых вычислений уже много лет стабильно развивается. Будущий крупномасштабный квантовый компьютер сможет с помощью алгоритма Шора, который умеет раскладывать целые числа на множители и решать задачу дискретного логарифмирования, нарушить безопасность широко используемых алгоритмов с открытым ключом, включая Rivest-Shamir-Adleman (RSA) и Diffie-Hellman. Платформа Java использует такие алгоритмы, помимо прочего, для цифровой подписи JAR-файлов и для установления защищённых сетевых соединений по протоколу Transport Layer Security (TLS). Атаку, на которую обычному суперкомпьютеру могли бы потребоваться от тысяч до миллионов лет, квантовый компьютер с алгоритмом Шора мог бы выполнить всего за несколько часов.
В ответ на эту угрозу криптографы разработали устойчивые к квантовым вычислениям криптографические алгоритмы, которые невозможно взломать алгоритмом Шора. Переходить на устойчивые к квантовым вычислениям алгоритмы нужно срочно, хотя крупномасштабных квантовых компьютеров ещё нет: злоумышленник может собирать зашифрованные данные уже сегодня, сохранять их и расшифровать, когда такие компьютеры появятся.
Для обмена ключами способом, устойчивым к квантовым вычислениям, NIST стандартизировал механизм инкапсуляции ключей на основе модульных решёток (ML-KEM) в FIPS 203. В США государственные компьютерные системы, обрабатывающие конфиденциальную информацию, должны в течение следующего десятилетия перейти на ML-KEM. Поэтому платформе Java необходимо предоставить реализацию этого алгоритма.
Описание
Как описано в JEP 452, KEM состоит из трёх функций:
-
Функция генерации пары ключей возвращает пару ключей, состоящую из открытого и закрытого ключа.
-
Функция инкапсуляции ключа вызывается отправителем и принимает открытый ключ получателя и параметр шифрования; она возвращает секретный ключ K и сообщение инкапсуляции ключа. Отправитель пересылает сообщение инкапсуляции ключа получателю.
-
Функция декапсуляции ключа вызывается получателем и принимает закрытый ключ получателя и полученное сообщение инкапсуляции ключа; она возвращает секретный ключ K.
Для первой функции мы предоставим реализацию API KeyPairGenerator, которая генерирует пары ключей ML-KEM. Для второй и третьей функций мы предоставим реализацию API KEM, которая согласует общие секретные ключи на основе пары ключей ML-KEM. Мы также предоставим реализацию API KeyFactory, которая преобразует ключи ML-KEM в их кодированное представление и обратно.
В Java Security Standard Algorithm Names Specification мы определим новое стандартное имя семейства алгоритмов "ML-KEM" для API KeyPairGenerator, KEM и KeyFactory.
FIPS 203 определяет для ML-KEM три набора параметров. В порядке возрастания криптостойкости и снижения производительности они называются "ML-KEM-512", "ML-KEM-768" и "ML-KEM-1024". Эти имена наборов параметров также будут определены как стандартные имена алгоритмов для API KeyPairGenerator, KEM и KeyFactory, а кроме того, будут представлены новыми константами NamedParameterSpec: ML_KEM_512, ML_KEM_768 и ML_KEM_1024.
Генерация пар ключей ML-KEM
Сгенерировать пару ключей ML-KEM можно одним из трёх способов:
-
Создать
KeyPairGeneratorпо имени семейства и инициализировать его именем набора параметров:KeyPairGenerator g = KeyPairGenerator.getInstance("ML-KEM"); g.initialize(NamedParameterSpec.ML_KEM_512); KeyPair kp = g.generateKeyPair(); // an ML-KEM-512 key pair -
Если не инициализировать
KeyPairGeneratorнабором параметров, реализация по умолчанию использует ML-KEM-768:KeyPairGenerator g = KeyPairGenerator.getInstance("ML-KEM"); KeyPair kp = g.generateKeyPair(); // an ML-KEM-768 key pair -
Создать
KeyPairGeneratorнепосредственно по имени набора параметров:KeyPairGenerator g = KeyPairGenerator.getInstance("ML-KEM-1024"); KeyPair kp = g.generateKeyPair(); // an ML-KEM-1024 key pair
API KeyPairGenerator позволяет указать при инициализации целочисленный размер ключа, но для пар ключей ML-KEM это не поддерживается и приведёт к выбросу InvalidParameterException.
Команда keytool будет поддерживать генерацию пар ключей и сертификатов ML-KEM. Например, чтобы сгенерировать пару ключей ML-KEM и подписать сертификат ключом EC:
$ keytool -keystore ks -storepass changeit -genkeypair -alias ec \
-keyalg ec -dname CN=ec -ext bc
$ keytool -keystore ks -storepass changeit -genkeypair -alias mlkem \
-keyalg ML-KEM -groupname ML-KEM-768 -dname CN=ML-KEM -signer ec
Первая команда создаёт пару ключей EC; вторая создаёт пару ключей ML-KEM и сертификат, подписанный ключом EC. Мы подписываем сертификат ключом EC, потому что ML-KEM сам по себе не является алгоритмом подписи и поэтому не может использоваться для подписи сертификата, содержащего открытый ключ ML-KEM.
Имя набора параметров (ML-KEM-768) можно также указать непосредственно в параметре -keyalg:
$ keytool -keystore ks -storepass changeit -genkeypair -alias mlkem2 \
-keyalg ML-KEM-768 -dname CN=ML-KEM2 -signer ec
Инкапсуляция и декапсуляция ключей ML-KEM
Для согласования общего секретного ключа можно использовать реализацию KEM для ML-KEM.
Например, отправитель может вызвать функцию инкапсуляции, чтобы получить секретный ключ и сообщение инкапсуляции ключа:
KEM ks = KEM.getInstance("ML-KEM");
KEM.Encapsulator enc = ks.newEncapsulator(publicKey);
KEM.Encapsulated encap = enc.encapsulate();
byte[] msg = encap.encapsulation(); // send this to receiver
SecretKey sks = encap.key();
Затем получатель может вызвать функцию декапсуляции, чтобы восстановить секретный ключ из сообщения инкапсуляции ключа, присланного отправителем:
byte[] msg = ...; // received from sender
KEM kr = KEM.getInstance("ML-KEM");
KEM.Decapsulator dec = kr.newDecapsulator(privateKey);
SecretKey skr = dec.decapsulate(msg);
sks и skr содержат одинаковый ключевой материал, известный только отправителю и получателю.
Если объект KEM создан по имени семейства, он принимает ключи ML-KEM этого семейства с любым набором параметров. Если он создан по имени набора параметров, он принимает только ключи ML-KEM, использующие этот набор параметров; в противном случае методы newEncapsulator и newDecapsulator выбрасывают InvalidKeyException.
Кодирование и декодирование ключей ML-KEM
С помощью реализации KeyFactory для ML-KEM можно преобразовать закрытый ключ ML-KEM в кодировку PKCS #8 и обратно или открытый ключ ML-KEM в кодировку X.509 и обратно.
Например, чтобы преобразовать закрытый ключ ML-KEM в кодировку PKCS #8 и обратно:
KeyFactory f = KeyFactory.getInstance("ML-KEM");
PKCS8EncodedKeySpec p8spec = f.getKeySpec(kp.getPrivate(),
PKCS8EncodedKeySpec.class);
PrivateKey sk2 = f.generatePrivate(p8spec);
Аналогично, чтобы преобразовать открытый ключ ML-KEM в кодировку X.509 и обратно:
X509EncodedKeySpec x509spec = f.getKeySpec(kp.getPublic(),
X509EncodedKeySpec.class);
PublicKey pk2 = f.generatePublic(x509spec);
Реализация KeyFactory может также преобразовать ключ другого провайдера безопасности с помощью метода translateKey, если формат его кодировки поддерживается.
Метод getAlgorithm объекта Key, созданного реализацией KeyPairGenerator или KeyFactory для ML-KEM, всегда возвращает имя семейства "ML-KEM", независимо от того, был ли KeyPairGenerator или KeyFactory создан по имени семейства "ML-KEM" или по одному из имён наборов параметров. Метод getParams ключа ML-KEM возвращает объект NamedParameterSpec, соответствующий имени набора параметров ключа.
Если объект KeyFactory создан по имени семейства, он кодирует и декодирует ключи ML-KEM этого семейства с любым набором параметров. Если он создан по имени набора параметров, он кодирует и декодирует только ключи ML-KEM, использующие этот набор параметров; в противном случае метод translateKey выбрасывает InvalidKeyException, а методы generatePrivate, generatePublic и getKeySpec выбрасывают InvalidKeySpecException.
Кодировка, используемая KeyFactory для ML-KEM, определена в черновике RFC IETF. Мы будем отслеживать изменения в этом черновике до его публикации.
Альтернативы
-
Проект Open Quantum Safe предоставляет обёртку JNI для своей библиотеки
liboqsна C, в которой реализован набор устойчивых к квантовым вычислениям алгоритмов, включая Kyber и ML-KEM. Если Open Quantum Safe достигнет своей цели и станет основной реализацией устойчивой к квантовым вычислениям криптографии для крупных проектов, таких как OpenSSL, BoringSSL, OpenSSH и Mozilla, то благодаря широкому тестированию и использованию она заметно выиграет в производительности и надёжности.По сравнению с нативной реализацией главное преимущество реализации ML-KEM на Java в том, что она встроена непосредственно в JDK. Благодаря этому она сразу доступна на всех платформах, на которые JDK уже портирован.
Тестирование
-
Модульные тесты подтвердят, что реализации соответствуют спецификациям API
KeyGenerator,KeyFactoryиKEM, в том числе в граничных случаях, таких как недопустимые входные параметры, граничные значения и неподдерживаемые операции. -
Тесты с известными ответами (Known Answer Tests, KAT) охватят как корректные криптографические операции (позитивные случаи), так и некорректные операции или известные уязвимости (негативные случаи), обеспечивая всестороннюю проверку. В их числе будут, помимо прочего:
-
KAT (здесь и здесь), сгенерированные сервисом Cryptographic Algorithm Validation Program NIST, и
-
Тесты ML-KEM из проекта Wycheproof, которые находятся в разработке.
-
-
Тесты совместимости с реализациями других поставщиков, включая, помимо прочего,
liboqs, подтвердят, что наша реализация ML-KEM корректно работает с другими.