Grizzly с TLS — проблема с рукопожатием

В настоящее время я пытаюсь защитить свой HTTP-сервер Grizzly с помощью SSL (что должно быть довольно просто в соответствии с руководствами и примерами) - только на стороне сервера. Итак, сначала я загрузил UnlimitedJCEPolicy из Orcale, чтобы иметь возможность поддерживать надежные алгоритмы TLS. Затем я создал новый файл хранилища ключей с помощью keytool и следующей команды:

keytool -keyalg rsa -keysize 2048 -genkey -keystore .\keystore_server.jks -alias server -dname "..."

Наконец, я настроил свой сервер со следующим кодом Java:

    //Create Http Server
    HttpServer server = new HttpServer();

    //Configure and register listener
    NetworkListener adminListener = new NetworkListener("admin", "localhost", 19241);

    SSLContextConfigurator configurator = new SSLContextConfigurator();
    URL url = configurator.getClass().getResource("/keystore_server.jks");
    if(url == null) throw new Error("Could not get Keystore!");
    configurator.setKeyStoreFile(url.getFile());
    configurator.setKeyStorePass("store");
    configurator.setKeyPass("key");
    configurator.setSecurityProtocol("TLS");


    SSLContext context = configurator.createSSLContext();
    SSLEngineConfigurator engineConfigurator = new SSLEngineConfigurator(context);
    engineConfigurator.setWantClientAuth(false);
    engineConfigurator.setClientMode(true);
    engineConfigurator.setNeedClientAuth(false);


    adminListener.setSSLEngineConfig(engineConfigurator);
    adminListener.setSecure(true);

    server.addListener(adminListener);

    Endpoint endpoint = new Endpoint();

    EndpointApplication application = new EndpointApplication(endpoint);

    HttpHandler httpHandler = RuntimeDelegate.getInstance().createEndpoint(application, HttpHandler.class);
    server.getServerConfiguration().addHttpHandler(httpHandler, "/test");

    server.start();

Благодаря Уоррену я решил первую проблему, не указав явно HTTPS в качестве используемого протокола. Однако сейчас возникла другая проблема. Вот журнал:

*** ClientHello, TLSv1
RandomCookie:  GMT: 1396054606 bytes = { 72, 223, 146, 247, 36, 165, 251, 160, 151, 23, 75, 48, 62, 242, 48, 178, 113, 150, 150, 62, 180, 118, 59, 232, 207, 168, 163, 93 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_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_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes:  len = 163
'...'
Grizzly(2) SelectorRunner, WRITE: TLSv1 Handshake, length = 163
[Raw write]: length = 168
'...'
[Raw read]: length = 5
'...'
[Raw read]: length = 171
'...'
Grizzly(2) SelectorRunner, READ: TLSv1 Handshake, length = 171
Grizzly(2) SelectorRunner, fatal error: 80: problem unwrapping net record
javax.net.ssl.SSLProtocolException: Handshake message sequence violation, 1
Grizzly(2) SelectorRunner, SEND TLSv1 ALERT:  fatal, description = internal_error
Grizzly(2) SelectorRunner, WRITE: TLSv1 Alert, length = 2

Кто-нибудь знаком с этим типом ошибок?


person htipk    schedule 28.03.2014    source источник
comment
Вы указываете URL-адрес https в браузере, а не http?   -  person Warren Dew    schedule 29.03.2014
comment
Хорошо, это была одна проблема точно! Я думал, что это будет согласовано автоматически, но это, очевидно, было не так. Однако проблема все еще существует, потому что теперь возникает исключение - я вставил его в конец своего исходного сообщения.   -  person htipk    schedule 29.03.2014
comment
TLS_ECDHE_ECDSA_* - вам нужен сертификат подписи (и закрытый ключ) с ECDSA. Но это не должно быть проблемой, поскольку доступны другие наборы шифров.   -  person jww    schedule 29.03.2014
comment
TLS_EMPTY_RENEGOTIATION_INFO_SCSV - это может быть проблемой. Я не помню, чтобы когда-либо видел, чтобы кто-то указывал это. OpenSSL обычно обрабатывает эту информацию на основе версий протокола. Кроме того, старые серверы не смогут с этим справиться. Какая версия OpenSSL используется на клиенте и сервере?   -  person jww    schedule 29.03.2014
comment
Вы можете подключиться к серверу с помощью openssl s_client -connect server:port -servername server -tls1? Вы можете включить свой сертификат CA с -CAfile, чтобы команда привела к Verify OK.   -  person jww    schedule 29.03.2014
comment
Ошибка подразумевает, что сервер получил приветственное сообщение клиента (тип сообщения 1, число в конце строки SSLProtocolException) после того, как сервер решил, что этот момент уже прошел в рукопожатии. Однако этого не должно происходить, если только в клиенте или сервере нет ошибки. Я согласен с предложением noloader попытаться открыть соединение в командной строке с помощью openssl.   -  person Warren Dew    schedule 29.03.2014
comment
Пожалуйста, установите для clientMode значение false: engineConfigurator.setClientMode(false);   -  person alexey    schedule 29.03.2014
comment
Алексей! Спасибо, что это было - можете ли вы объяснить мне, почему это не сработало с clientMode true?   -  person htipk    schedule 29.03.2014
comment
clientMode предназначен для соединений на стороне клиента, вы находитесь на стороне сервера :)   -  person alexey    schedule 29.03.2014
comment
Ах, ладно, я бы использовал режим клиента, если бы использовал SSLEngine для подключения к серверу, защищенному с помощью SSL.   -  person htipk    schedule 29.03.2014
comment
да (мне нужно добавить больше символов, чтобы опубликовать комментарий :))   -  person alexey    schedule 01.04.2014
comment
@jww EMPTY_RENEGOTIATION_INFO_SCSV: OP использует Java JSSE, а не OpenSSL. OpenSSL изначально отправляет только SCSV, поэтому нет возможности указать; JSSE поддерживает как (пустое) расширение, так и SCSV, но по умолчанию используется SCSV, который лучше работает со старыми серверами, чем расширение, как описано в RFC 5746.   -  person dave_thompson_085    schedule 05.12.2014
comment
Какие пакеты вы используете для Endpoint и EndpointApplication? Моя среда IDE (NetBeans 8.1) не находит совместимый (с используемыми параметрами) класс конечной точки и не находит ничего, реализующего конечную точку. У меня та же проблема: я пытаюсь заставить Grizzly (встроенную в автономную реализацию Tyrus/Grizzly WebSocket JSR 356) запускать безопасную конечную точку wss вместо того, чтобы игнорировать тот факт, что URI предназначен для wss, и решить вместо этого использовать ws. .   -  person Darrin    schedule 09.05.2016


Ответы (1)


У меня была точно такая же проблема, при использовании параметра командной строки -Djavax.net.debug=all я нашел эту строку журнала:

Grizzly(2) SelectorRunner, fatal error: 80: problem unwrapping net record

Основываясь на комментариях Алексея, я изменил код на:

engineConfigurator.setClientMode(false);
engineConfigurator.setNeedClientAuth(false);

После этого изменения фатальная ошибка исчезает, и я могу получить доступ к application.wadl через https с помощью браузера.

Я потерял довольно много времени на поиск решения, было бы неплохо, если бы Grizzly сообщил об этой проблеме в более читабельной и понятной форме.

person Rolf    schedule 03.11.2015