在Websphere 8.0上使用JSSEHelper以编程方式指定出站SSL配置.不起作用 [英] Specifying an outbound SSL configuration programmatically using JSSEHelper on Websphere 8.0. does not work

查看:108
本文介绍了在Websphere 8.0上使用JSSEHelper以编程方式指定出站SSL配置.不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用WAS 8.0.0.13(使用Java 1.6.0的IBM Websphere应用程序服务器)中配置的CUSTOM出站ssl配置以编程方式创建SSL连接: (安全性-> SSL证书和密钥管理->相关项目:SSL配置). 安全连接已成功创建:驻留在WAS服务器上的servlet已连接到侦听127.0.0.1:1234的服务器端套接字. 问题是,我在SSL配置的保护质量(QoP)设置"中定义的首选密码套件将被忽略. 所有其他属性(例如协议或JSSE提供程序)都被很好地考虑了.

I am trying to create an SSL connection programmatically using a CUSTOM outbound ssl configuration configured in WAS 8.0.0.13 (IBM Websphere application server that uses java 1.6.0): (Security->SSL certificate and key managemement->Related Items:SSL configurations). The secure connection has been created successfully:a servlet that resides on the WAS server has connected to a server-side Socket listening on 127.0.0.1:1234. The problem is that my preferred cipher suites defined in 'Quality of Protection (QoP) settings' within SSL configuration are ignored. All the other properties (such as protocol or JSSE provider) are nicely regarded.

我已经实现了一个充当SSL客户端角色的Servlet. 该Servlet使用了此自定义SSL配置,该配置定义了以下密码套件:

I have implemented a Servlet which was in the role of an SSL-client. This Servlet used this custom SSL configuration which had the following cipher suites defined:

  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请求中提供了不同的密码套件列表:

Unfortunately, a different list of cipher suites has been provided in ClientHello request:

  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
  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协议.)

(This custom SSL configuration contained TLSv1.1 protocol in its definition.)

我还尝试了另一套带有较小密码套件的协议(TLSv1.2):

I have also tried another protocol (TLSv1.2) with a smaller set of cipher suites:

  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请求中提供了另一组密码套件:

Once again, a different list of cipher suites was provided in ClientHello request:

  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中提供的匹配: 默认节点配置/默认单元配置:

Moreover, I have also checked cell-default cipher suites and node-default-cipher-suites and there is no match between them and those provided in the ClientHello: Default Node Configuration/Default Cell Configuration:

  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

我已按照以下说明进行操作:

I have followed these instructions: https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/tsec_ssloutconfiguseJSSE.html

并创建了以下实现. 'doGet'方法是一个切入点:

and have created the following implementation. 'doGet' method is an entry point:

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的存在似乎并不重要. 设置为null还是不包含任何值都没有关系.

The presence of the hash map sslMap seems to be of no importance. It does not matter whether is set to null or contains no values.

我还尝试在线程上强制使用ssl属性(该属性在所有其他属性中具有最高的优先级): 这种方法也行不通:

I have also tried to enforce ssl properties on thread (this one has the highest preference among all the others): This approach also dodn't worked:

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);
}

最后,我尝试不绑定到WAS服务器SSL配置中存在的任何SSL配置,而仅使用我的Java代码连接自定义配置:

Finally, I have tried not to bind to any SSL configuration present in WAS server SSL configs, but only wire up a custom configuration with my java code:

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配置.

But this approach also did not work. Could you please help me? I suppose I missed something principal or custom SSL configuration does not exist in this product.

推荐答案

因此,由于我最初并未仔细查看您的代码.我看到了问题.因为您直接从JSSEHelper获得了Socket工厂,所以我们没有机会将密码放到套接字上.

So due to my not looking at your code carefully initially. I see the problem. Because you get the Socket factory directly from the JSSEHelper, we are not getting the chance to put the ciphers on the socket.

在您的情况下,您应该遵循WAS的编程SSL方法.获取属性并将其放在线程上.例如

In your case you should follow the WAS's programmatic SSL methods. Get the properties and put them on the thread. eg

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

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

以后不要从JSSE获取Socket工厂,请获取默认值.因此,在getSslSocket()中执行以下操作:

The later don't get the Socket factory from the JSSE, get the default. So in getSslSocket() do something like:

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上设置了密码的套接字.完成后,应清除线程的属性.

This will get you a WAS socket factory. The create socket call should return you a socket with the ciphers set on the SSLSocket. When you are done you should clear the properties off the thread.

jsseHelper.setSSLPropertiesOnThread(null);

这篇关于在Websphere 8.0上使用JSSEHelper以编程方式指定出站SSL配置.不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆