Указание исходящей конфигурации SSL программно с использованием JSSEHelper на Websphere 8.0. не работает

Я пытаюсь создать SSL-соединение программно с использованием исходящей конфигурации ssl CUSTOM, настроенной в WAS 8.0.0.13 (сервер приложений IBM Websphere, использующий java 1.6.0): (Безопасность-> Управление сертификатом SSL и ключами-> Связанные элементы: Конфигурации SSL). Защищенное соединение успешно создано: сервлет, находящийся на сервере WAS, подключился к сокету на стороне сервера, прослушивающему 127.0.0.1:1234. Проблема заключается в том, что мои предпочтительные комплекты шифров, определенные в "Настройках качества защиты (QoP)" в конфигурации SSL, игнорируются. Все остальные свойства (такие как протокол или поставщик JSSE) хорошо рассматриваются.

Я реализовал сервлет, который был в роли SSL-клиента. Этот сервлет использовал эту пользовательскую конфигурацию SSL, в которой были определены следующие наборы шифров:

  1. SSL_RSA_WITH_AES_128_CBC_SHA
  2. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  3. SSL_DHE_DSS_WITH_AES_128_CBC_
  4. SHA SSL_RSA_WITH_AES_128_GCM_SHA256
  5. SSL_RSA_WITH_AES_128_CBC_SHA256
  6. SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
  7. SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
  8. SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
  9. SSL_DHE_DSS_WITH_AES_128_CBC_SHA256

К сожалению, другой список комплектов шифров был предоставлен в запросе ClientHello:

  1. SSL_RSA_WITH_AES_128_CBC_SHA
  2. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  3. SSL_DHE_DSS_WITH_AES_128_CBC_SHA
  4. SSL_RSA_WITH_3DES_EDE_CBC_SHA
  5. SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
  6. SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
  7. SSL_RSA_WITH_DES_CBC_SHA
  8. SSL_DHE_RSA_WITH_DES_CBC_SHA
  9. SSL_DHE_DSS_WITH_DES_CBC_SHA
  10. SSL_RENEGO_PROTECTION_REQUEST

(Эта пользовательская конфигурация SSL содержала протокол TLSv1.1 в своем определении.)

Я также попробовал другой протокол (TLSv1.2) с меньшим набором наборов шифров:

  1. SSL_RSA_WITH_AES_128_CBC_SHA
  2. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  3. SSL_DHE_DSS_WITH_AES_128_CBC_SHA
  4. SSL_DHE_DSS_WITH_AES_128_CBC_SHA256

Еще раз, другой список наборов шифров был предоставлен в запросе ClientHello:

  1. SSL_RSA_WITH_AES_128_CBC_SHA
  2. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  3. SSL_DHE_DSS_WITH_AES_128_CBC_SHA
  4. SSL_RSA_WITH_3DES_EDE_CBC_SHA
  5. SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA

Кроме того, я также проверил наборы шифров по умолчанию для ячеек и наборы узлов по умолчанию, и нет совпадения между ними и теми, которые указаны в ClientHello: Конфигурация узла по умолчанию / Конфигурация ячейки по умолчанию:

  1. SSL_RSA_WITH_AES_128_CBC_SHA
  2. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  3. SSL_DHE_DSS_WITH_AES_128_CBC_SHA
  4. SSL_RSA_WITH_AES_128_GCM_SHA256
  5. SSL_RSA_WITH_AES_128_CBC_SHA256
  6. SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
  7. SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
  8. SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
  9. SSL_DHE_DSS_WITH_AES_128_CBC_SHA256

Я следовал этим инструкциям: https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/tsec_ssloutconfiguseJSSE.html

и создали следующую реализацию. Метод doGet является точкой входа:

public class TLSv1_1 extends HttpServlet {
private static final long serialVersionUID = 1L;
com.ibm.websphere.ssl.JSSEHelper jsseHelper;

public TLSv1_1() {
    super();
    jsseHelper = com.ibm.websphere.ssl.JSSEHelper.getInstance();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    Properties existing_sslProps = null;
    try {
        String existingAlias = "TLSv1.1";
        existing_sslProps = jsseHelper.getProperties(existingAlias);

    } catch (com.ibm.websphere.ssl.SSLException e) {
        e.printStackTrace();
    }
    printSSLproperties(response, existing_sslProps);
    SSLSocket socket = getSslSocket(existing_sslProps);
    writeToSocket(socket, 1234);
}

public static void printSSLproperties(HttpServletResponse response, Properties sslProps) throws IOException {
    if (sslProps != null) {
        StringBuilder sb = new StringBuilder();
        Set set = sslProps.entrySet();
        Iterator it = set.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            Object value = entry.getValue();
            sb.append("key: " + entry.getKey() + ", value: " + value + "\n");
        }
        System.out.println("sslProps:    -----------\n" + sb.toString());           
    } else {
        System.out.println("sslProps == null");
        response.getWriter().append("sslProps == null");
    }
}

public SSLSocket getSslSocket(Properties sslProps) {
    Map<String, Object> sslMap = new HashMap<String, Object>();

    sslMap.put("com.ibm.ssl.direction", "outbound");
    sslMap.put("com.ibm.ssl.remoteHost", "127.0.0.1");
    sslMap.put("com.ibm.ssl.remotePort", "1234");
    sslMap.put("com.ibm.ssl.endPointName", "HTTP");
    SSLSocketFactory sslSocketFactory = null;
    try {
        sslSocketFactory = jsseHelper.getSSLSocketFactory(sslMap, sslProps);
    } catch (SSLException e) {
        e.printStackTrace();
    }

    SSLSocket socket = null;
    try {
        socket = (SSLSocket) sslSocketFactory.createSocket();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return socket;
}

public static void writeToSocket(Socket socket, int port) throws IOException, UnknownHostException {

    InetAddress address = InetAddress.getByName("127.0.0.1");
    socket.connect(new InetSocketAddress(address, port));
    BufferedWriter stream = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

    for (int i = 0; i < 3; i++) {
        String lineX = UUID.randomUUID().toString();
        stream.write(lineX);
        stream.newLine();
        stream.flush();
        System.out.println("NEW LINE SUCCESSFULLY WRITTEN INTO SOCKET:" + lineX);
        sleep();
    }
}

private static void sleep() {

    try {
        Thread.sleep(1000 * 30);
    } catch (InterruptedException e) {

    }
} 

}

Наличие хэш-карты sslMap, похоже, не имеет значения. Не имеет значения, установлено ли значение в ноль или не содержит значений.

Я также попытался применить свойства ssl в потоке (этот метод имеет наибольшее предпочтение среди всех остальных): этот подход также не сработал:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String existingAlias = "TLSv1.1";
existing_sslProps = jsseHelper.getProperties(existingAlias);

jsseHelper.setSSLPropertiesOnThread(existing_sslProps);

CommonIO.printSSLproperties(response, existing_sslProps);       
SSLSocket socket = getSslSocket(existing_sslProps);
CommonIO.writeToSocket(socket, 1234);

jsseHelper.setSSLPropertiesOnThread(null);
}

Наконец, я попытался не привязывать ни одну конфигурацию SSL, присутствующую в конфигурациях SSL WAS-сервера, а только соединить пользовательскую конфигурацию с моим Java-кодом:

sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.1");
    sslProps.setProperty("com.ibm.ssl.enabledCipherSuites",
            "SSL_DHE_DSS_WITH_AES_128_CBC_SHA SSL_DHE_DSS_WITH_AES_128_GCM_SHA256 SSL_DHE_DSS_WITH_AES_128_CBC_SHA256");
    sslProps.setProperty("com.ibm.ssl.trustStore",
            "/opt/IBM/Websphere/profiles/AppSrv01/config/cells/localhostCell01/nodes/localhostNode01/trust.p12");
    sslProps.setProperty("com.ibm.ssl.trustStorePassword", "***");
    sslProps.setProperty("com.ibm.ssl.trustStoreType", "PKCS12");
    sslProps.setProperty("com.ibm.ssl.keyStore",
            "/opt/IBM/Websphere/profiles/AppSrv01/config/cells/localhostCell01/key.p12");
    sslProps.setProperty("com.ibm.ssl.keyStorePassword", "***");
    sslProps.setProperty("com.ibm.ssl.keyStoreType", "PKCS12");

    sslProps.setProperty("security.provider.1", "com.ibm.jsse2.IBMJSSEProvider2");
    sslProps.setProperty("ssl.SocketFactory.provider", "com.ibm.jsse2.SSLSocketFactoryImpl");

Но этот подход также не сработал. Не могли бы вы мне помочь? Я предполагаю, что пропустил что-то основное или пользовательская конфигурация SSL не существует в этом продукте.

4 ответа

Решение

Так что из-за того, что я не смотрю на ваш код внимательно изначально. Я вижу проблему. Поскольку вы получаете фабрику сокетов непосредственно от JSSEHelper, у нас нет возможности поставить шифры на сокет.

В вашем случае вы должны следовать программным методам SSL WAS. Получите свойства и поместите их в поток. например

 try {
        String existingAlias = "TLSv1.1";
        existing_sslProps = jsseHelper.getProperties(existingAlias);
    jsseHelper.setSSLPropertiesOnThread(existing_sslProps);

    } catch (com.ibm.websphere.ssl.SSLException e) {
        e.printStackTrace();
    } 

Позднее не получите фабрику сокетов от JSSE, получите значение по умолчанию. Так что в getSslSocket() сделать что-то вроде:

public SSLSocket getSslSocket(Properties sslProps) {

    SSLSocketFactory factory = SSLSocketFactory.getDefault();

    SSLSocket socket = null;
    try {
        socket = (SSLSocket) factory.createSocket();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return socket;
}

Это даст вам фабрику розеток WAS. Вызов create socket должен вернуть вам сокет с установленными на SSLSocket шифрами. Когда вы закончите, вы должны удалить свойства из потока.

jsseHelper.setSSLPropertiesOnThread(null);

Я смотрю на ошибку, связанную с использованием конфигурации SSL с именем "TLSv1.1". 2 из 3 настроенных вами шифров не поддерживаются TLSv1.1, более подробную информацию о шифре, поддерживаемом IBM java 6, вы можете найти здесь https://www.ibm.com/support/knowledgecenter/es/SSYKE2_6.0.0/com.ibm.java.security.component.60.doc/security-component/jsse2Docs/ciphersuites.html?view=embed. Это оставляет вас с одним шифром, SSL_DHE_DSS_WITH_AES_128_CBC_SHA.

[12/17/17 6:16:19:524 EST] 00000000 SystemOut     O   Ignoring unsupported cipher suite: SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
[12/17/17 6:16:19:524 EST] 00000000 SystemOut     O   Ignoring unsupported cipher suite: SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
[12/17/17 6:16:19:527 EST] 00000000 SystemOut     O   %% No cached client session
[12/17/17 6:16:19:528 EST] 00000000 SystemOut     O   *** ClientHello, TLSv1.1
[12/17/17 6:16:19:528 EST] 00000000 SystemOut     O   RandomCookie:  GMT: 1513509379 bytes = { 108, 16, 192, 144, 124, 116, 226, 48, 69, 61, 93, 187, 104, 67, 120, 166, 233, 194, 67, 244, 136, 159, 105, 130, 106, 175, 18, 251 }
[12/17/17 6:16:19:529 EST] 00000000 SystemOut     O   Session ID:  {}
[12/17/17 6:16:19:529 EST] 00000000 SystemOut     O   Cipher Suites: [SSL_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RENEGO_PROTECTION_REQUEST] 

Это соединение идет к порту 9202 на том же хосте, 127.0.0.1. И в конечном итоге заканчивается ошибка, javax.net.ssl.SSLHandshakeException: получено фатальное предупреждение: handshake_failure. Я думаю, что ваш сервер пытается связаться с вашим агентом узла с неправильной конфигурацией SSL. Кажется, эта конфигурация выбрана из фильтра динамического выбора исходящих сообщений.

[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3   SSLConfig dynamic selection info: *,127.0.0.1,*
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3   Parsing entry 0 of 1: *,127.0.0.1,*
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3   This entry has 3 attributes.
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3   Protocol: *, Host: 127.0.0.1, Port: *
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3   Found a dynamic selection match!
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana <  getPropertiesFromDynamicSelectionInfo -> found. Exit

Ваш фильтр будет соответствовать чему-либо, идущему к 127.0.0.1, чтобы использовать конфигурацию SSL под названием "TLSv1.1". Кажется, что это соединение использует протокол TLSv1. Таким образом, соединение не удается из-за несоответствия протокола. Кажется, эта конфигурация SSL не предназначена для использования с доступом к 127.0.0.1 и порту 9202. Может ли это быть агент локального узла или порт dmgr? Если это так, соединение должно быть связано с NodeDefaultSSLSettings.

Для меня не очевидно, что соединение говорит с вашим сервером, локальным хостом и портом 1234. Возможно, если вы исправите свою конфигурацию так, чтобы узел использовал правильную конфигурацию SSL при переходе на порт 9202 и 127.0.0.1, это может быть проще выяснить.

Спасибо за ваши советы! Я следовал этим инструкциям:

https://www-01.ibm.com/support/docview.wss?uid=swg21162961

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

Я собрал файлы журналов только из этих подкаталогов:

  1. ../logs/server1
  2. ../logs/nodeagent
  3. ../logs/ffdc и поместил их в каталог ALL_LOGS/logs в этих файлах:

https://drive.google.com/open?id=18TMYyjKx8L_pd8TxFG1uq1rOmikVyWeg

, так что, если есть и другие файлы журнала / трассировки в разных местах, пожалуйста, дайте мне знать. (В этих файлах присутствует только Delta, поскольку я очистил все файлы журнала / трассировки перед запуском сервера и повторным тестированием сценария.)

Я нашел только это в логах ffdc:

The client and server could not negotiate the desired level of security.Reason: Received fatal alert: handshake_failure vmcid: 0x49421000 minor code: 70 completed: No

Я не уверен, является ли коренная причина моей проблемы, но никакие результаты Google, казалось, не относились к моей проблеме. Что касается результатов Google, я имел в виду следующее:

https://www.ibm.com/developerworks/community/forums/html/topic?id=a2910c33-8f55-4ef7-823d-7ae367682e35

http://www.dsxchange.com/viewtopic.php?t=134492&sid=f6e236a4f14a9d80fc51c0820e5f7ce7 Ни один из них не помог...

Наряду с подкаталогами log-файлов я также присоединяю стандартный вывод сокета сервера со stderr в TLSv1.1_enforce_OnThread.log. Кроме того, я также прилагаю конфигурацию на стороне клиента CONFIG_TLSv1.1._ENFORSE_SSL_ON_THREAD.png

Не могли бы вы проверить эти файлы журнала? Спасибо, честно, большое.

-- Майкл

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

Я также изменил список поддерживаемых наборов шифров на стороне WAS (на стороне клиента) на основе предоставленной вами отличной ссылки!:-). Точнее, я выбрал только эти комплекты, потому что они поддерживаются всеми протоколами TLS (TLSv1.0, TLSv1.1, TLSv1.2):

  1. SSL_RSA_WITH_AES_128_CBC_SHA
  2. SSL_RSA_WITH_3DES_EDE_CBC_SHA
  3. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  4. SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
  5. SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA

Я снова очистил все файлы журнала и запустил сервер приложений. После повторного тестирования моего сценария эта дельта в лог-файлах была сгенерирована: https://drive.google.com/open?id=19KaDlsx2UVS_YfByaORQOf89mLlJke4e

Серверное приложение, которое прослушивает порт 1234, поддерживает те же наборы шифров:

  1. SSL_RSA_WITH_AES_128_CBC_SHA
  2. SSL_RSA_WITH_3DES_EDE_CBC_SHA
  3. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  4. SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
  5. SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA

Конечно, я не ожидал, что проблема будет решена после этих изменений, но я ожидал, что я найду некоторые ошибки в журналах / трассировках, чтобы уменьшить нагрузку на вас. К сожалению, мне не удалось. Не могли бы вы проверить эти журналы / следы? Спасибо, честно, большое спасибо!

(Пожалуйста, игнорируйте это исключение:

Исключение FFDC:java.net.MalformedURLException SourceId: класс com.ibm.wkplc.extensionregistry.PluginDescriptor.initFromDom ProbeId:1

присутствует в файле server1_b7f67871_17.12.19_04.44.51.8551967663872103714940.txt, так как я еще раз проверил его (в третий раз), и это исключение не появилось после 3-го повторного тестирования.)

Другие вопросы по тегам