SSLSockets и проблемы со спецификациями шифров - PullRequest
2 голосов
/ 21 декабря 2009

Я пытаюсь, чтобы мой клиент Java связался с сервером C с помощью SSL.

Проблема в том, что у меня нет источников на сервере, и я получаю ошибку сбоя при рукопожатии:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1657)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
        at posslu.Main.main(Main.java:36)
Java Result: 1

После некоторого сверхпрочного перехвата я теперь знаю, что у работающих клиентов C (у меня также нет доступа к их исходному коду) есть эти спецификации Cipher в пакетах приветствия клиент-сервер:

Cipher Spec: SSL2_DES_192_EDE3_CBC_WITH_MD5 (0x0700c0)
Cipher Spec: SSL2_IDEA_128_CBC_WITH_MD5 (0x050080)
Cipher Spec: SSL2_RC2_CBC_128_CBC_WITH_MD5 (0x030080)
Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080)
Cipher Spec: SSL2_RC4_64_WITH_MD5 (0x080080)
Cipher Spec: SSL2_DES_64_CBC_WITH_MD5 (0x060040)
Cipher Spec: SSL2_RC2_CBC_128_CBC_WITH_MD5 (0x040080)
Cipher Spec: SSL2_RC4_128_EXPORT40_WITH_MD5 (0x020080)

и все пакеты отправляются по протоколу SSLv2.

А это спецификации метода SSLSocket.getSupportedCipherSuites ():

SSL_RSA_WITH_RC4_128_MD5   
SSL_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_DHE_RSA_WITH_DES_CBC_SHA
SSL_DHE_DSS_WITH_DES_CBC_SHA
SSL_RSA_EXPORT_WITH_RC4_40_MD5
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
SSL_RSA_WITH_NULL_MD5
SSL_RSA_WITH_NULL_SHA
SSL_DH_anon_WITH_RC4_128_MD5
TLS_DH_anon_WITH_AES_128_CBC_SHA
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
SSL_DH_anon_WITH_DES_CBC_SHA
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_KRB5_WITH_RC4_128_SHA
TLS_KRB5_WITH_RC4_128_MD5
TLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_DES_CBC_SHA
TLS_KRB5_WITH_DES_CBC_MD5
TLS_KRB5_EXPORT_WITH_RC4_40_SHA
TLS_KRB5_EXPORT_WITH_RC4_40_MD5
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5

Теперь я хочу использовать

Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080)

так как кажется, что он поддерживается и сервером C, и моим клиентом java. Итак, я придумал этот код:

SSLSocketFactory sslsockfact = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsockfact.createSocket( args[0], args[1] );

sslsocket.setEnabledCipherSuites( new String[] { "SSL_RSA_WITH_RC4_128_MD5" } );
sslsocket.startHandshake();

Но по какой-то причине эти спецификации шифров отправляются в пакете приветствия клиента:

Cipher Spec: TLS_RSA_WITH_RC4_128_MD5 (0x000004)
Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080)

Разве не должен быть включен только второй? Это приводит к тому, что сервер отправляет пакет hello server по протоколу TLSv1, и вызывает ошибку рукопожатия.

Я продолжал пытаться выяснить, что происходит:

Это поддерживаемые протоколы, которые я получил от getSupportedProtocols ():

SSLv2Hello
SSLv3
TLSv1

Если я добавлю что-то подобное в мой код:

sslsocket.setEnabledProtocols( new String[] { "SSLv2Hello" } );

Там написано:

Exception in thread "main" java.lang.IllegalArgumentException: SSLv2Hellocannot be enabled unless TLSv1 or SSLv3 is also enabled

Если я переключусь на:

sslsocket.setEnabledProtocols( new String[] { "SSLv2Hello", "SSLv3" } );

сервер отвечает в SSLv3, и я получаю ошибку рукопожатия ...

Так вот, я понятия не имею, как заставить это работать, любая помощь?

Возможно ли, что SSLv2 больше не поддерживается, и я просто не могу использовать его с Java?

1 Ответ

1 голос
/ 08 июля 2013

Поставщик JDK JSSE не поддерживает SSL v2, который по своей сути является небезопасным протоколом. Поддержка SSLv2Hello предназначена для совместимости с SSLv3 для некоторых серверов, которые могут иметь ошибки протокола и нуждаются в v2 hello. Этот SSLv2Hello удален в JDK7.

Для реального разговора поддерживаются только SSLv3 и TLS. Поэтому, если ваш сервер поддерживает только SSL v2, вам нужно обновить сервер - v2 небезопасен и не должен использоваться.

SSL_RSA_WITH_RC4_128_MD5 и TLS_RSA_WITH_RC4_128_MD5 - это один и тот же набор шифров, но JSSE HotSpot, когда запрашивается набор поддерживаемых наборов через SSLSocketFactory.getSupportedCipherSuites(), сообщает только первый. Текущий анализатор протокола Wireshark сообщит TLS_RSA_WITH_RC4_128_MD5 (0x0004), что может привести к путанице.

Смотри также:

Как инициировать ssl-соединение с использованием SSLv2 http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html

Редактировать : так как я упомянул выше, что SSLv2 очень устарел и небезопасен, я чувствую, что должен также упомянуть, что поскольку эксплойт SSLv3 POODLE опубликован, SSLv3 также считается небезопасный и устаревший.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...