
Плагин-фильтр Kroxylicious, обеспечивающий прозрачное постквантовое (ML-KEM + AES-256-GCM) шифрование на уровне записей для Apache Kafka, не требующее изменений клиентского кода.
A Kroxylicious filter plugin that provides transparent Post-Quantum Cryptography (PQC) record-level encryption for Apache Kafka using ML-KEM (FIPS 203) key encapsulation with AES-256-GCM symmetric encryption.
Kafka producers and consumers require zero code changes. The Kroxylicious proxy intercepts traffic and encrypts on Produce / decrypts on Fetch automatically.``` Producer ──plaintext──> Kroxylicious ──encrypted──> Kafka Broker Consumer <──plaintext── Kroxylicious <──encrypted── Kafka Broker
## Зачем нужен PQC для Kafka?
Классические алгоритмы установки ключей (RSA, ECDH) уязвимы перед будущими
квантовыми компьютерами. Если ключи шифрования для каждой записи устанавливаются
с помощью классического KEM, квантовый противник сможет восстановить эти ключи
из капсуляций, хранящихся вместе с шифротекстом на брокере.
Этот плагин использует ML-KEM (FIPS 203) для квантово-устойчивой инкапсуляции ключей,
гарантируя, что данные, хранящиеся на брокере Kafka, не могут быть расшифрованы даже
противником, обладающим криптографически значимым квантовым компьютером.
**Примечание:** Этот фильтр защищает **данные, хранящиеся на брокере**, а не
TLS-канал при передаче. Полный анализ того, от чего обеспечивается и не обеспечивается
защита, см. в [THREAT_MODEL.md](https://github.com/oscerd/kroxylicious-pqc-filter/blob/main/THREAT_MODEL.md).
| Стандарт | Алгоритм | Назначение в этом плагине |
|----------|-----------|------------------------|
| FIPS 203 | ML-KEM (Kyber) | Инкапсуляция ключа — надёжно устанавливает AES-ключ для каждого сообщения |
| N/A | AES-256-GCM | Симметричное аутентифицированное шифрование полезной нагрузки записи |
| N/A | X25519 ECDH | Классическое согласование ключей для гибридного режима (эшелонированная защита) |
## Возможности
- **Прозрачное шифрование/дешифрование** — не требует изменений на стороне клиента
- **Наборы параметров ML-KEM-512, ML-KEM-768 (по умолчанию), ML-KEM-1024**
- **Гибридный режим** (по умолчанию) — объединяет ML-KEM + X25519 ECDH, так что взломать нужно оба
- **Шифрование каждой записи** — каждая запись получает свежую капсуляцию KEM + случайный IV
- **Фильтрация топиков** — регулярные выражения выбирают, какие топики шифровать
- **Обнаружение подделки** — аутентифицированное шифрование AES-GCM отклоняет изменённый шифротекст
- **Семантическая безопасность** — одинаковые открытые тексты дают разные шифротексты (IND-CCA2)
- **Автоматическая генерация ключей** — при первом запуске создаёт и сохраняет ключи ML-KEM, если они отсутствуют
- **Заголовок `x-pqc-encrypted`** — помечает зашифрованные записи для информирования нижестоящих компонентов
- **Подключаемые поставщики ключей** — SPI `KeyProvider` поддерживает файловую систему (по умолчанию) и бэкенды HashiCorp Vault
## Предварительные требования
| Требование | Версия |
|-------------|---------|
| JDK | 17+ (рекомендуется 21+) |
| Maven | 3.8+ |
| Kroxylicious | 0.19.0 |
| Apache Kafka | 3.9.x |
## Быстрый старт
### 1. Сборка плагина```bash
git clone <this-repo>
cd kroxylicious-pqc-filter
mvn clean package -DskipTests
Shaded JAR-файл по пути target/kroxylicious-pqc-filter-1.0.0-SNAPSHOT.jar включает Bouncy Castle, поэтому его можно просто поместить в Kroxylicious без дополнительных зависимостей.
Чтобы включить поддержку поставщика ключей HashiCorp Vault, выполните сборку с профилем vault:```bash
mvn clean package -Pvault -DskipTests
Это объединяет `spring-vault-core` и `VaultKeyProvider` в JAR.
### 2. Сгенерируйте ключи ML-KEM```bash
java -cp target/kroxylicious-pqc-filter-1.0.0-SNAPSHOT.jar \
io.kroxylicious.filter.pqc.PqcKeyGeneratorCli \
ML_KEM_768 \
/etc/kroxylicious/pqc/
Вывод:``` Generating ML-KEM-768 key pair... Public key: /etc/kroxylicious/pqc/pqc-public.der Size: 1206 bytes Format: X.509 Private key: /etc/kroxylicious/pqc/pqc-private.der Size: 2498 bytes Format: PKCS#8
В качестве альтернативы можно опустить пути к ключам в конфигурации — фильтр сгенерирует ключи автоматически при первом запуске.
### 3. Настройка Kroxylicious
Добавьте фильтр в YAML-конфигурацию вашего прокси Kroxylicious:```yaml
filterDefinitions:
- name: pqc-encryption
type: PqcRecordEncryptionFilterFactory
config:
kemAlgorithm: ML_KEM_768
hybridMode: true
publicKeyPath: /etc/kroxylicious/pqc/pqc-public.der
privateKeyPath: /etc/kroxylicious/pqc/pqc-private.der
topicPatterns:
- "sensitive-.*"
- "pii-.*"
defaultFilters:
- pqc-encryption
Поместите JAR-файл в каталог, доступный для Kroxylicious, и добавьте его в
classpath через переменную окружения KROXYLICIOUS_CLASSPATH:```bash
export KROXYLICIOUS_CLASSPATH="/opt/kroxylicious/plugins/*"
При использовании Docker задайте его в среде вашего контейнера:```yaml
environment:
KROXYLICIOUS_CLASSPATH: /opt/kroxylicious/plugins/*
Затем запустите прокси. Производители и потребители подключаются к порту прокси, а не напрямую к брокеру.
| Свойство | Тип | Обязательность | По умолчанию | Описание |
|---|---|---|---|---|
kemAlgorithm | enum | Нет | ML_KEM_768 | Параметр ML-KEM. Один из ML_KEM_512, ML_KEM_768, ML_KEM_1024. |
hybridMode | boolean | Нет | true | Объединяет ML-KEM с X25519 ECDH для эшелонированной защиты. |
publicKeyPath | string | Только для файловой системы | - | Путь в файловой системе к открытому ключу ML-KEM (в кодировке X.509 DER). |
privateKeyPath | string | Только для файловой системы | - | Путь в файловой системе к закрытому ключу ML-KEM (в кодировке PKCS#8 DER). |
topicPatterns | list<string> | Нет | [".*"] | Шаблоны Java regex. Шифруются/расшифровываются только записи в темах, соответствующих шаблонам. |
keyProviderType | string | Нет | filesystem | Бэкенд хранения ключей. Один из filesystem, vault. |
keyProviderConfig | map<string, string> | Только для Vault | {} | Конфигурация, специфичная для бэкенда (см. раздел Vault ниже). |
Filesystem (keyProviderType: filesystem, по умолчанию):
Загружает ключи ML-KEM из DER-файлов на диске. Если файлы не существуют, генерирует новую пару ключей и сохраняет их. Требует publicKeyPath и privateKeyPath.
HashiCorp Vault (keyProviderType: vault, требует сборки с -Pvault):
Получает ключи ML-KEM из движка секретов Vault KV v2. Ключи хранятся в виде DER в кодировке base64 в полях publicKey и privateKey. Версии секретов Vault сопоставляются с идентификаторами ключей для поддержки ротации ключей.
Свойства Vault keyProviderConfig:
| Свойство | Обязательность | По умолчанию | Описание |
|---|---|---|---|
vaultAddress | Да | переменная окружения VAULT_ADDR | URL сервера Vault (например, http://vault:8200) |
vaultToken | Для аутентификации token | переменная окружения VAULT_TOKEN | Токен аутентификации Vault |
secretPath | Да | -- | Путь внутри движка секретов (например, kroxylicious/pqc) |
secretEngine | Нет | secret | Имя точки монтирования движка секретов KV v2 |
authMethod | Нет | token | Метод аутентификации: token, approle или kubernetes |
roleId | Для approle | -- | Идентификатор роли AppRole |
secretId | Для approle | -- | Секретный идентификатор AppRole |
kubeRole | Для kubernetes | -- | Имя роли аутентификации Kubernetes |
kubeTokenPath | Нет | /var/run/secrets/.../token | Путь к файлу токена сервисного аккаунта |