Java: криптографические уязвимости и анти-паттерны (2025)
Криптография в Java строится вокруг JCA/JCE, провайдеров (SunJCE, Bouncy Castle и др.), TLS-стека и зависимостей из экосистемы Maven/Gradle. Ошибки конфигурации и выбора примитивов по-прежнему чаще ломают безопасность, чем «взлом алгоритмов». Ниже собраны типовые уязвимости, анти-паттерны и практические меры для команд, пишущих на Java сервисы, кошельки, бэкенды и интеграции с блокчейном.
Почему это важно в 2025 году
Больше ончейн-интеграций и платежей повышает ценность ключей и токенов доступа: компрометация даёт прямые финансовые потери.
Риск supply-chain: компрометированные зависимости/плагины CI/CD приводят к внедрению вредоносной криптологии на этапе сборки (см. Supply-chain атаки — как защитить криптопроекты).
Частые zero-day в экосистеме JVM и сторонах окружения повышают требования к реакциям и патчингу (см. Zero-day уязвимости: что это и как защититься (чек-лист)).
Карта рисков: где чаще всего ошибаются
| Зона | Типовые уязвимости | Итоговый риск |
|---|---|---|
| Симметричное шифрование | AES в ECB или CBC без аутентификации; неверные IV/nonce; повтор IV в CTR/GCM | Раскрытие структуры данных, подмена, расшифровка блоков |
| Аутентифицированное шифрование | Неправильное использование AES-GCM/ChaCha20-Poly1305: повтор nonce, игнор GCM tag | Изменение данных без обнаружения, расшифровка |
| Ключи и случайность | Неправильный сеед SecureRandom, общий IV/nonce, утечки приватных ключей | Предсказуемые ключи/токены, компрометация |
| Ассиметрия | RSA с PKCS#1 v1.5, ECDSA с повтором nonce, неверный размер ключей | Padding oracle, подделка подписи |
| Хэширование и MAC | Использование MD5/SHA-1; сравнение секретов без time-constant | Коллизии, тайминг-атаки |
| TLS | Не проверяются цепочки/hostname, запрет проверки сертификатов, слабые шифры | MITM, расшифровка трафика |
| Хранение ключей | Плоские файлы, JKS без защиты, ключи в переменных окружения/логах | Кража ключей и подпись мошеннических транзакций |
| Зависимости | Устаревшие библиотеки crypto/TLS, уязвимые загрузчики, плагины Maven | Внедрение бэкдоров, RCE |
| Диагностика | Открытый JDWP/отладка на проде без туннеля (см. JDWP (Java Debug Wire Protocol): что это и как защитить прод) | Исполнение кода и утечка секретов |
Частые анти-паттерны и безопасные альтернативы
| Анти-паттерн | Чем плохо | Что делать правильно |
|---|---|---|
| AES/ECB или CBC без MAC | Нет семантической безопасности и аутентичности | Использовать AEAD: AES-GCM или ChaCha20-Poly1305 |
| Случайный IV, но повторяется или фиксирован | Повтор IV рушит безопасность режимов CTR/GCM | Уникальный nonce на сообщение, хранить/передавать вместе с шифртекстом |
| Свой формат «подписи» на JSON | Уязвимости каноникализации/подмены полей | Использовать стандарты (JWS/CMS) и проверять каноникализацию |
| RSA-PKCS1 v1.5 | Padding oracle при некорректных обработках | RSA-OAEP для шифрования, RSASSA-PSS для подписей; лучше ЭЦП на эллиптических кривых |
| MD5/SHA-1 | Коллизии и предобраз | SHA-256/512, SHA-3; для MAC - HMAC-SHA-256 |
| equals для секретов | Утечка по времени сравнения | Константное сравнение (MessageDigest.isEqual) |
| TrustAll/disable hostname | Полная потеря TLS-валидации | Полная проверка цепочки X.509 и hostname verifier |
| Ключи в конфиге/логах | Лёгкая компрометация | Keystore PKCS#12, HSM/KMS, secret stores, маскирование логов |
Практика: как это работает в Java-стеке
JCA/JCE провайдеры. Правильный выбор алгоритмов/режимов и поставщика критичен. Bouncy Castle актуален как расширение, но обновляйте версии, фиксируйте провайдера и параметры.
SecureRandom. Используйте надёжные источники по умолчанию, не переинициализируйте ручным предсказуемым seed. Для nonce в GCM - 96 бит, уникальность на сообщение.
AES-GCM. Следите за уникальным nonce, длиной тега 128 бит. Никогда не переиспользуйте nonce с одним ключом.
ECDSA/EdDSA. Для ECDSA контролируйте генерацию случайного nonce (RFC 6979 детерминированный k уменьшает риск ошибок). Ed25519 даёт устойчивость к ошибкам nonce по дизайну.
TLS. Строгая валидация сертификатов, список шифров без слабых алгоритмов, ALPN и SNI включены. Не отключайте hostname verification.
Keystore. Предпочитайте PKCS#12, разграничивайте права доступа, интегрируйте с HSM/KMS если возможно. Не храните пароли/ключи в переменных окружения без шифрования на стороне оркестратора.
Журналы и метрики. Маскируйте секреты, не логируйте ключевой материал и IV/nonce. В проде исключите уровень TRACE для криптографии.
CI/CD и зависимости. Подписи артефактов, lock-файлы/версионирование, локальные зеркала артефактов, сканирование SBOM. Любые «горячие» обновления - через canary и откат.
Мини-таблица решений по задачам
| Задача | Рекомендуемые примитивы | Примечания |
|---|---|---|
| Шифрование данных | AES-GCM, ChaCha20-Poly1305 | Уникальный nonce, тег 128 бит, дополнительные данные для связывания контекста |
| Подпись сообщений | Ed25519 или ECDSA P-256 (с RFC 6979) | Проверка формата, каноникализация данных |
| Хэширование | SHA-256/512, SHA3-256/512 | Избегать MD5/SHA-1 |
| Деривация ключей | PBKDF2, scrypt, Argon2 (через проверенный провайдер) | Адекватные параметры cost, соль уникальна |
| Случайные значения | SecureRandom.getInstanceStrong() или дефолтный | Не задавать предсказуемый seed |
| TLS клиент/сервер | TLS 1.2+ с современными шифрами | Полная проверка цепочки и имени хоста |
Чек-лист перед продом
- Элемент ненумерованного спискаАлгоритмы и режимы: нет ECB/CBC без аутентификации, только AEAD.
- Ключи и nonce: уникальность и длины проверены, нет повторов, есть аудит генераторов.
- TLS: hostname verification включен, нет TrustAll, включены актуальные шифры.
- Keystore/секреты: PKCS#12/HSM/KMS, политика ротации, запрет логирования ключей.
- Зависимости: обновлены, подписаны, SBOM отсканирован, есть план отката.
- JDWP и диагностика: нет открытых дебаг-портов на проде, туннели и доступы по регламенту (см. JDWP (Java Debug Wire Protocol): что это и как защитить прод).
- Инциденты: готов трейл ранбука, алерты на ошибки AEAD, провалы валидации сертификатов и аномалии nonce.
FAQ
Почему AES-GCM иногда «ломается» в отчётах пентестеров? Чаще всего из-за повторного использования nonce или неверной работы с тегами. AEAD безопасен только при корректной уникальности nonce и проверке тега.
Стоит ли переходить с ECDSA на Ed25519? Для новых систем Ed25519 упрощает правильную реализацию и устойчив к ошибкам nonce. Если уже используете ECDSA, применяйте детерминированный nonce и проверенную библиотеку.
Безопасен ли дефолтный SecureRandom в JVM? Да, используйте системные источники. Не переопределяйте seed вручную и не кэшируйте один экземпляр на весь процесс без понимания последствий.
Можно ли отключить проверку сертификатов ради отладки? Только локально и временно. В проде это превращает TLS в простой шифрованный, но небезопасный туннель.
Нужен ли HSM/KMS в каждом проекте? Зависит от угроз и суммы под риском. Минимум - изоляция ключей, PKCS#12, разграничение доступов и автоматизированная ротация.