Какие типы SSL/TLS сертификатов и хранилищ вы используете в Java-приложениях?

«Какие типы SSL/TLS сертификатов и хранилищ вы используете в Java-приложениях?» — вопрос из категории Безопасность, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Java-приложениях для безопасных соединений (HTTPS, LDAPS, etc.) используются сертификаты X.509.

1. Типы сертификатов и источники:

  • Сертификаты, подписанные Удостоверяющим Центром (CA): (например, Let's Encrypt, DigiCert). JVM по умолчанию доверяет корневым сертификатам из встроенного хранилища cacerts.
  • Самоподписанные (self-signed) сертификаты: для разработки или внутренних сетей. Требуют явного добавления в доверенное хранилище.

2. Хранилища ключей (KeyStore) и типы:

  • PKCS12 (.p12 или .pfx) — современный, стандартный формат. Рекомендуется к использованию. Содержит и приватные ключи, и цепочки сертификатов.
    KeyStore ks = KeyStore.getInstance("PKCS12");
    ks.load(new FileInputStream("keystore.p12"), "password".toCharArray());
  • JKS (Java KeyStore) — устаревший, проприетарный формат Java. Следует мигрировать на PKCS12.

3. Доверенные хранилища (TrustStore): Отдельный KeyStore (часто тот же cacerts), содержащий корневые и промежуточные сертификаты CA, которым доверяет клиент.

4. Практическое использование:

// Настройка SSLContext с собственным KeyStore и TrustStore
SSLContext sslContext = SSLContexts.custom()
        .loadKeyMaterial(keyStore, "keyPassword".toCharArray()) // Ваш сертификат
        .loadTrustMaterial(trustStore, null) // Доверенные CA
        .build();

// Использование в HTTP-клиенте (например, Apache HttpClient)
CloseableHttpClient client = HttpClients.custom()
        .setSSLContext(sslContext)
        .build();

Важно: Для продакшена всегда используйте сертификаты от доверенных CA. Отключение проверки (TrustAllStrategy) допустимо только в тестовых средах.