У нас возникли проблемы с запуском приложения Java из-за сбоя подтверждения связи. При проверке мы обнаружили, что приложение не может подключиться к серверу, поскольку сервер ожидает определенный набор шифров (TLS_RSA_WITH_AES_256_CBC_SHA256), но клиент не имеет его в своем приветственном сообщении.
Я хотел бы знать, есть ли способ позволить клиенту использовать набор шифров в своем приветствии. Я не большой эксперт в SSL/TLS, что мне нужно понять, чтобы справиться с этим?
Java-версия:
openjdk version "11.0.22" 2024-01-16 LTS
OpenJDK Runtime Environment (Red_Hat-11.0.22.0.7-1) (build 11.0.22+7-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-11.0.22.0.7-1) (build 11.0.22+7-LTS, mixed mode, sharing)
Запись java.security jdk.tls.disabledAlgorithms:
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves
Запись java.security jdk.disabled.namedCurves:
jdk.disabled.namedCurves = secp112r1, secp112r2, secp128r1, secp128r2, \
secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, \
secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, \
sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, \
sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, \
sect571k1, sect571r1, X9.62 c2tnb191v1, X9.62 c2tnb191v2, \
X9.62 c2tnb191v3, X9.62 c2tnb239v1, X9.62 c2tnb239v2, X9.62 c2tnb239v3, \
X9.62 c2tnb359v1, X9.62 c2tnb431r1, X9.62 prime192v2, X9.62 prime192v3, \
X9.62 prime239v1, X9.62 prime239v2, X9.62 prime239v3, brainpoolP256r1, \
brainpoolP320r1, brainpoolP384r1, brainpoolP512r1
Запись java.security crypto.policy:
crypto.policy=unlimited
Я создал автономный класс Java, который печатает все поддерживаемые шифры и протоколы (на стороне клиента):
try {
SSLContext sslContext = SSLContext.getDefault();
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
System.out.println("Supported Ciphers:");
for (String cipher: sslSocketFactory.getSupportedCipherSuites()) {
System.out.println(cipher);
}
System.out.println("\nSupported Protocols:");
for (String protocol: sslContext.getSupportedSSLParameters().getProtocols()) {
System.out.println(protocol);
}
} catch (Exception e) {
e.printStackTrace();
}
Это результат:
Supported cipher suites:
TLS_AES_256_GCM_SHA384
TLS_AES_128_GCM_SHA256
TLS_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
TLS_RSA_WITH_NULL_SHA256
TLS_ECDHE_ECDSA_WITH_NULL_SHA
TLS_ECDHE_RSA_WITH_NULL_SHA
SSL_RSA_WITH_NULL_SHA
Supported protocols:
TLSv1.3
TLSv1.2
TLSv1.1
TLSv1
SSLv3
SSLv2Hello
Как видите, «TLS_RSA_WITH_AES_256_CBC_SHA256» не упоминается. Как я могу включить этот конкретный набор шифров? Несколько дней назад, я не знаю как, но набор шифров появился в списке. Я действительно не знаю, что мы сделали, поэтому знаю, что это возможно. Теперь он не отображается, потому что мы изменили установку Java (но в любом случае обе были Java 11).
(@g00se), как и (мой) Oracle 11.0.22+9-LTS-219 - и версии как старые, так и новые, вплоть до 22(.0.0). Маурисио: чтобы внести ясность, вы запускаете тестовый класс напрямую (т.е. как «основной») в своей JVM, а не встроен в какое-либо более крупное приложение, инфраструктуру или платформу? Какова запись в вашем $JAVA/conf/security/java.security для jdk.tls.disabledAlgorithms (пожалуйста, отредактируйте ее в Q, а не в качестве комментария) и есть ли какие-либо указания на то, что она (или файл) была изменена после установки?
Также обратите внимание, что SSLv3 и TLSv1 сегодня абсолютно не следует использовать, а TLSv1.1 не следует использовать, если этого можно избежать, и в пакетах Oracle они отключены, а в вашем, по-видимому, нет. Последние системы RedHat (начиная с версии 8 IIRC) имеют общесистемную криптографическую политику, которая отменяет некоторые индивидуальные настройки программы. Есть ли у вас такая система, и если да, то на что она настроена?
Спасибо за комментарии. @dave_thompson_085 Тестовый класс является автономным, кроме того, я отредактировал вопрос, включив в него несколько строк из файла java.security, который я редактировал раньше, но в настоящее время он у меня есть в том виде, в каком он есть в наличии. И да, моя система — Red Hat Enterpirse Linux 8.6 (Ootpa).
Хм, странно, вы указали, что TLSv1.1 отключен, а поддержка TLSv1.1 в поддерживаемых протоколах есть? Что-то не так с конфигурацией.
@MaartenBodewes+ игнорируй то, что я сказал о версиях; Я перепроверил, и «поддерживаемые протоколы» НЕ отражают настройки отключения (в отличие от «поддерживаемых наборов шифров»). Ваши настроенные параметры отключения такие же, как у меня, но вы все равно получаете другой результат, включая «нулевые» наборы, которые должны быть отключены в соответствии с вашей конфигурацией; было бы неплохо вызвать (в JVM Failing=RedHat) java.security.Security.getProperty("jdk.tls.disabledAlgorithms")
и посмотреть, отличается ли это как-то, хотя я вижу, что вы нашли обходной путь и, возможно, не захотите беспокоиться.
Итак, я решил проблему, и да, она была связана с дистрибутивом Java, который я использовал.
Я использовал дистрибутив Java от Red Hat Inc., установленный через репозитории Red Hat с помощью yum, но, судя по всему, Java от RH не поддерживает тот набор шифров, который я искал. Комментарий @ g00se как бы помог мне, когда они упомянули «лицензирование». Итак, основываясь на комментариях, которые я получил по моему вопросу, я пошел и скачал .rpm для Java, но на этот раз Oracle.
После этого я установил его на свой сервер RHEL:
rpm -ivh jdk-11.0.21_linux-x64_bin.rpm
А затем запустил мой класс, чтобы проверить, были ли добавлены какие-либо новые наборы шифров, и, конечно же, это было «TLS_RSA_WITH_AES_256_CBC_SHA256».
После этого я просто указал в своем служебном файле (тот, который запускает приложение, в котором произошел сбой квитирования) использовать Java Oracle, вот так:
ExecStart=/usr/lib/jvm/jdk-11-oracle-x64/bin/java ...other options... -jar "application.war"
И всё заработало нормально, ошибок больше нет!
Спасибо за все ваши комментарии, они мне очень помогли :)
Без проблем. «Лицензирование» было для меня немного расплывчатым. На самом деле я имел в виду ЭТО
Ради интереса я только что запустил это с Open JDK 8, и он есть. Возможно, проблема с лицензией (?)