Ошибки аутентификации Google при доступе к конечной точке токена из JVM

Мы запускаем веб-приложение с серверной частью JVM (обновление Java 7 75; код находится на Scala, но я не думаю, что это актуально). Мы используем Google для аутентификации через Oauth.

За последние пару месяцев было несколько дней, когда нам периодически не удавалось аутентифицировать пользователей.

Перенаправление в Google и из Google выполняется успешно, но когда мы пытаемся вызвать token_endpoint по адресу https://www.googleapis.com/oauth2/v4/token для проверки аутентификации мы иногда получаем следующее исключение: javax.net.ssl.SSLHandshakeException: server certificate change is restrictedduring renegotiation.

Этот комментарий к другому вопросу привел меня к обнаружению ошибки JDK, которая может проявляться как это исключение (Что означает javax.net.ssl.SSLHandshakeException: изменение сертификата сервера ограничено во время повторного согласования и как это предотвратить?).

Моя рабочая гипотеза:

Ошибка (https://bugs.openjdk.java.net/browse/JDK-8072385) означает, что проверяется только первая запись в списке альтернативных имен субъекта (SAN). Приведенное выше исключение возникает, когда проверяемое имя хоста находится в списке SAN, но не находится в верхней части списка.

Вчера (27 мая 2015 г. из ) мы увидели два разных сертификата, которые с перерывами обслуживались с www.googleapis.com. Первый (серийный номер 67:1a:d6:10:cd:1a:06:cc) имел список SAN из DNS:*.googleapis.com, DNS:*.clients6.google.com, DNS:*.cloudendpointsapis.com, DNS:cloudendpointsapis.com, DNS:googleapis.com, а второй (серийный номер 61:db:c8:52:b4:77:cf:78) имел список SAN из: DNS:*.storage.googleapis.com, DNS:*.commondatastorage.googleapis.com, DNS:*.googleapis.com.

Из-за ошибки в JVM мы можем проверить первый сертификат, но исключение выдается со вторым (несмотря на то, что он полностью действителен), поскольку *.googleapis.com не является первой записью в списке SAN.

Исправление находится в еще не выпущенном 7u85 (без упоминания о том, когда оно будет доступно).

Я понизил рейтинг одного узла нашего кластера до 7u65, но сертификат, похоже, был отменен примерно в то время, когда мы это сделали (последняя ошибка, которую мы видели, была 22:20 по Гринвичу), поэтому трудно определить положительное исправление.

Кто-нибудь еще сталкивался с этим или чем-то подобным и имел ли какой-либо другой обходной путь, кроме понижения версии (при понижении версии удаляются различные другие проверки SSL/TLS)?


person sihil    schedule 28.05.2015    source источник


Ответы (1)


Я не совсем уверен, что ваша проблема связана с ошибкой JVM.

В Java 6 и более поздних версиях есть исправление для CVE-2014-6457, «Атака тройного рукопожатия против соединений TLS/SSL (JSSE, 8037066)», предотвращающая изменение одноранговых сертификатов во время повторного согласования.

Объяснение проблемы:

Уязвимость во всех версиях протокола Transport Layer Security (TLS) (включая более старый протокол Secure Socket Layer (SSLv3)) может сделать возможными атаки типа Man-In-The-Middle (MITM), когда выбранный обычный текст вводится в качестве префикса для TLS-соединение. Эта уязвимость не позволяет злоумышленнику расшифровать или изменить перехваченное сетевое соединение после того, как клиент и сервер успешно договорились о сеансе между собой.

Однако, если потенциально измененный сертификат предназначен для того же удостоверения, что и последний просмотренный сертификат, тогда подключение разрешено.

В этом случае два идентификатора считаются равными:

  • В обоих сертификатах указано альтернативное имя субъекта, которое является IP-адресом, и IP-адрес в обоих сертификатах одинаков.
  • В обоих сертификатах указано альтернативное имя субъекта, которое является DNS-именем, и DNS-имя в обоих сертификатах одинаково.
  • Поля субъекта и издателя присутствуют в обоих сертификатах и ​​содержат идентичные значения субъекта и издателя.

В других условиях (удостоверение сертификата изменилось) возникает исключение javax.net.ssl.SSLHandshakeException: server certificate change is restricted during renegotiation.

Обходной путь:

  • Отключить повторное согласование (не рекомендуется), применяя следующий аргумент JVM: -Djdk.tls.allowUnsafeServerCertChange=true отключает небезопасную защиту сертификата сервера.
  • Отключите SSLv3 в исходящих соединениях HTTPS, Java 7 поддерживает TLSv1.1 и TLSv1.2 в режиме клиента, но по умолчанию использует TLSv1 в подтверждении TLS. Мы также должны использовать TLSv1.1 и TLSv1.2 в клиентском режиме TLS в java 7. Java 8 включает протоколы TLSv1.1 и TLSv1.2 в клиентском режиме (в дополнение к SSLv3 и TLSv1) и по умолчанию использует TLSv1.2 при рукопожатии TLS. Если вы создаете соединение программно и устанавливаете фабрику сокетов, используйте TLS вместо SSL.

В любом случае, обновите свой пост кодом клиента oauth google, прежде чем вызывать token_endpoint, чтобы подтвердить аутентификацию и посмотреть, что может произойти.

person vzamanillo    schedule 05.06.2015
comment
пожалуйста, взгляните: stackoverflow.com/questions/58844821/ - person gstackoverflow; 14.11.2019