Java - Как отключить шифрование TLS только для некоторых протоколов с помощью JVM Config?

Я видел множество примеров отключения TLS-шифров в java, используя jdk.tls.disabledAlgorithms, например:

 jdk.tls.disabledAlgorithms=MD2, RSA keySize < 1024, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

Но как я могу отключить шифр только для определенных протоколов, используя jdk.tls.disabledAlgorithms или аналогичную конфигурацию?

Например, как я могу отключить TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 для TLSv1.1 только?

Кажется, он не поддерживает метод opensssl, который выглядит так:

TLSv1.1:!TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

Он не вызывает никаких ошибок, но шифр по-прежнему разрешен.

EDIT: Обратите внимание, что меня действительно интересуют только ответы на основе JVM-конфигурации, так как я не контролирую код, который на многих этих серверах, только конфигурации JVM и JVM. Некоторые из них - даже сторонние серверы, поэтому больше вещей на уровне ops, чем что-либо.

EDIT 2: Обратите внимание, что вы можете запускать приложение java и поставлять аргументы, которые изменяют используемые протоколы и шифры, например java -server -Djava.security.properties=./my/custom/java.security -jar myapp.jar сделают это, но это не позволит вам фильтровать шифры по протоколу, только шифрам или протоколам, из того, что я вижу. Файл будет содержать запись свойства, такую как jdk.tls.disabledAlgorithms

Ответ 1

Отправка моего комментария в качестве ответа, потому что почему бы и нет.

Другие ответы и каждый документ, который я нашел в Интернете, похоже, согласны с тем, что то, о чем вы просите, невозможно сделать в Java, по крайней мере пока. Вы можете включать/отключать протоколы по всему миру, и вы можете включать/отключать типы шифров по всему миру, но вы не можете делать это на основе другого.

Однако, поскольку вы находитесь на стороне DevOps, возможно, возможно решение, отличное от Java. Вы можете запускать отдельные экземпляры приложения, каждый из которых имеет только TLSv1.1, только TLSv1.2 и т.д., И применять необходимый фильтр шифрования для каждого; а затем nginx (или что вы используете) перенаправляет трафик на соответствующий экземпляр в зависимости от обнаруженного протокола.

Итак, один пример в NODE1:

jdk.tls.client.protocols=TLSv1.1
jdk.tls.disabledAlgorithms=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

Другой пример в NODE2:

jdk.tls.client.protocols=TLSv1.2
jdk.tls.disabledAlgorithms=...

И некоторые правила nginx (используйте return или rewrite как вы сочтете нужным):

server {
    [...]
    if ( $ssl_protocol = TLSv1.1 ) {
        return 302 $scheme://NODE1.yourhost.com$request_uri;
    }
    if ( $ssl_protocol = TLSv1.2 ) {
        rewrite ^ $scheme://NODE2.yourhost.com$request_uri;
    }

Я просто разработчик Java, мой опыт работы с nginx очень ограничен, поэтому вам может понадобиться немного настроить конфигурацию. Просто пытаюсь помочь.

Ответ 2

Документы JSSE говорят, что свойство https.protocols может хранить список поддерживаемых протоколов с запятыми в определенном контексте SSL, однако это свойство используется текущей реализацией JSSE, но может быть проигнорировано другими поставщиками или будущими версиями, поэтому YMMV.

Программно вы можете добиться этого так:

SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
socket.setEnabledCipherSuites(new String[] {
    CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName,
    CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName,
});

//allow TLS1.2 only
socket.setEnabledProtocols(new String[] {
    TlsVersion.TLS_1_2.javaName,
});

Ответ 3

edit lib/security/java.security (может быть в другом месте на основе вашего JDK) и добавить Algorithm в jdk.tls.disabledAlgorithms

В дополнение к этому keySize может использоваться для ограничения более слабых алгоритмов. jdk.tls.disabledAlgorithms=MD2, MD4, MD5, EC keySize < 160, RSA keySize < 2048, DSA keySize < 2048

Я полагаю, вы уже все это знаете и действительно хотите иметь эти версии (в идеале что-то вроде jdk.tls11.disabledAlgorithms), однако я не знаю ни одного такого мелкозернистого свойства.

Тем не менее, версия протокола может быть ограничена как таковая jdk.tls.client.protocols=TLSv1.1

Если вы хотите поддерживать TLSv1.1 и TLSv1.2 хорошей стратегией будет поддержка только этих алгоритмов (или настройка keySize алгоритмов), чтобы они были сильны в обеих версиях TLS.

Для справки: https://www.java.com/ru/configure_crypto.html