在 Websphere 8.0 上使用 JSSEHelper 以编程方式指定出站 SSL 配置。不起作用
Specifying an outbound SSL configuration programmatically using JSSEHelper on Websphere 8.0. does not work
我正在尝试使用在 WAS 8.0.0.13(使用 java 1.6.0 的 IBM Websphere 应用程序服务器)中配置的自定义出站 ssl 配置以编程方式创建 SSL 连接:
(安全->SSL 证书和密钥管理->相关 Items:SSL 配置)。
已创建安全连接 successfully:a 驻留在 WAS 服务器上的 servlet 已连接到侦听 127.0.0.1:1234 的服务器端套接字。
问题是我在 SSL 配置中 'Quality of Protection (QoP) settings' 中定义的首选密码套件被忽略了。
所有其他属性(例如协议或 JSSE 提供程序)都很好。
我实现了一个充当 SSL 客户端角色的 Servlet。
此 Servlet 使用此自定义 SSL 配置,其中定义了以下密码套件:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_
- SHA SSL_RSA_WITH_AES_128_GCM_SHA256
- SSL_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
很遗憾,ClientHello 请求中提供了不同的密码套件列表:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_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_RENEGO_PROTECTION_REQUEST
(此自定义 SSL 配置在其定义中包含 TLSv1.1 协议。)
我还尝试了另一种协议 (TLSv1.2) 和一组较小的密码套件:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
ClientHello 请求中再次提供了不同的密码套件列表:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
此外,我还检查了cell-default cipher suites和node-default-cipher-suites,没有
它们与 ClientHello 中提供的匹配:
默认节点 Configuration/Default 单元格配置:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_AES_128_GCM_SHA256
- SSL_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
并创建了以下实现。 '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 的存在似乎并不重要。
设置为 null 或不包含任何值都没有关系。
我还尝试在线程上强制执行 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);
}
最后,我尝试不绑定到 WAS 服务器 SSL 配置中存在的任何 SSL 配置,而只使用我的 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 配置在该产品中不存在。
感谢您的提示!我遵循了这些说明:
https://www-01.ibm.com/support/docview.wss?uid=swg21162961
根据您的提示提高 log/trace 等级。
如果我必须进行一些其他配置更改,请告诉我。
我只从这些子目录中收集了日志文件:
- ../logs/server1
- ../logs/nodeagent
- ../logs/ffdc
并将它们放入这些文件中的 ALL_LOGS/logs 目录中:
https://drive.google.com/open?id=18TMYyjKx8L_pd8TxFG1uq1rOmikVyWeg
,所以如果在不同位置还有其他 log/trace 文件,请告诉我。
(只有 Delta 存在于这些文件中,因为我清除了所有 log/trace 文件
在启动服务器并重新测试我的场景之前。)
我在 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 结果而言,我的意思是这些:
http://www.dsxchange.com/viewtopic.php?t=134492&sid=f6e236a4f14a9d80fc51c0820e5f7ce7
None 其中有帮助...
除了日志子目录,我还在 TLSv1.1_enforce_OnThread.log 中附加服务器端套接字标准输出和标准错误。
此外,我还附加了客户端配置 CONFIG_TLSv1.1._ENFORSE_SSL_ON_THREAD.png
你能检查一下这些日志文件吗?
非常感谢。
--
迈克尔
我正在查看涉及使用名为 "TLSv1.1" 的 SSL 配置的错误。 TLSv1.1 不支持您配置的 3 个密码中的 2 个,您可以在此处 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 找到有关 IBM java6 支持的密码的更多信息。
这给你留下了一个密码,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]
此连接将连接到同一主机 127.0.0.1 上的端口 9202。最终以错误结束,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 的内容,以使用名为 "TLSv1.1" 的 SSL 配置。这个连接似乎使用的是 TLSv1 协议。因此,由于协议不匹配,连接失败。似乎此 SSL 配置不打算用于访问 127.0.0.1 和端口 9202。这可能是您的本地节点代理或 dmgr 端口吗?如果是这样,连接需要 NodeDefaultSSLSettings。
在跟踪中,我看不出什么连接正在与您的服务器、本地主机和端口 1234 通信。也许如果您修复您的配置,以便节点在转到端口 9202 和 127.0 时将使用正确的 SSL 配置。 0.1 可能更容易算出来。
感谢您的大力支持&swift回复!
根据您的输入,我删除了 SSL 配置设置中存在的所有动态出站规则。
我也修改了支持的密码套件列表
在 WAS 端(客户端),基于您提供的 link!:-)。
更准确地说,我只选择了这些套房
因为所有 TLS 协议(TLSv1.0、TLSv1.1、TLSv1.2)都支持它们:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
我再次清除了所有日志文件,然后启动了应用程序服务器。
重新测试我的方案后,已生成日志文件中的此增量:
https://drive.google.com/open?id=19KaDlsx2UVS_YfByaORQOf89mLlJke4e
监听1234端口的服务端应用同样支持
密码套件:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
当然没想到改完之后问题就解决了
但我预计我会在 logs/traces 中发现一些错误,以减轻强加给您的负担。不幸的是,我没有成功。你能检查一下这些 logs/traces 吗?非常感谢!
(请忽略此异常:
FFDC Exception:java.net.MalformedURLException SourceId:class com.ibm.wkplc.extensionregistry.PluginDescriptor.initFromDom ProbeId:1
存在于 server1_b7f67871_17.12.19_04.44.51.8551967663872103714940.txt 文件中,
因为我再次重新测试它(第 3 次)并且在第 3 次重新测试后没有出现此异常。)
所以由于我最初没有仔细查看您的代码。我看到了问题。因为您直接从 JSSEHelper 获取套接字工厂,所以我们没有机会将密码放在套接字上。
在您的情况下,您应该遵循 WAS 的编程 SSL 方法。获取属性并将它们放在线程上。例如
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() 中做类似的事情:
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 套接字工厂。创建套接字调用应该 return 为您提供一个在 SSLSocket 上设置了密码的套接字。完成后,您应该清除线程中的属性。
jsseHelper.setSSLPropertiesOnThread(null);
我正在尝试使用在 WAS 8.0.0.13(使用 java 1.6.0 的 IBM Websphere 应用程序服务器)中配置的自定义出站 ssl 配置以编程方式创建 SSL 连接: (安全->SSL 证书和密钥管理->相关 Items:SSL 配置)。 已创建安全连接 successfully:a 驻留在 WAS 服务器上的 servlet 已连接到侦听 127.0.0.1:1234 的服务器端套接字。 问题是我在 SSL 配置中 'Quality of Protection (QoP) settings' 中定义的首选密码套件被忽略了。 所有其他属性(例如协议或 JSSE 提供程序)都很好。
我实现了一个充当 SSL 客户端角色的 Servlet。 此 Servlet 使用此自定义 SSL 配置,其中定义了以下密码套件:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_
- SHA SSL_RSA_WITH_AES_128_GCM_SHA256
- SSL_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
很遗憾,ClientHello 请求中提供了不同的密码套件列表:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_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_RENEGO_PROTECTION_REQUEST
(此自定义 SSL 配置在其定义中包含 TLSv1.1 协议。)
我还尝试了另一种协议 (TLSv1.2) 和一组较小的密码套件:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
ClientHello 请求中再次提供了不同的密码套件列表:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
此外,我还检查了cell-default cipher suites和node-default-cipher-suites,没有 它们与 ClientHello 中提供的匹配: 默认节点 Configuration/Default 单元格配置:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_AES_128_GCM_SHA256
- SSL_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
- SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
并创建了以下实现。 '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 的存在似乎并不重要。 设置为 null 或不包含任何值都没有关系。
我还尝试在线程上强制执行 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);
}
最后,我尝试不绑定到 WAS 服务器 SSL 配置中存在的任何 SSL 配置,而只使用我的 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 配置在该产品中不存在。
感谢您的提示!我遵循了这些说明:
https://www-01.ibm.com/support/docview.wss?uid=swg21162961
根据您的提示提高 log/trace 等级。 如果我必须进行一些其他配置更改,请告诉我。
我只从这些子目录中收集了日志文件:
- ../logs/server1
- ../logs/nodeagent
- ../logs/ffdc 并将它们放入这些文件中的 ALL_LOGS/logs 目录中:
https://drive.google.com/open?id=18TMYyjKx8L_pd8TxFG1uq1rOmikVyWeg
,所以如果在不同位置还有其他 log/trace 文件,请告诉我。 (只有 Delta 存在于这些文件中,因为我清除了所有 log/trace 文件 在启动服务器并重新测试我的场景之前。)
我在 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 结果而言,我的意思是这些:
http://www.dsxchange.com/viewtopic.php?t=134492&sid=f6e236a4f14a9d80fc51c0820e5f7ce7 None 其中有帮助...
除了日志子目录,我还在 TLSv1.1_enforce_OnThread.log 中附加服务器端套接字标准输出和标准错误。 此外,我还附加了客户端配置 CONFIG_TLSv1.1._ENFORSE_SSL_ON_THREAD.png
你能检查一下这些日志文件吗? 非常感谢。
-- 迈克尔
我正在查看涉及使用名为 "TLSv1.1" 的 SSL 配置的错误。 TLSv1.1 不支持您配置的 3 个密码中的 2 个,您可以在此处 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 找到有关 IBM java6 支持的密码的更多信息。 这给你留下了一个密码,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]
此连接将连接到同一主机 127.0.0.1 上的端口 9202。最终以错误结束,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 的内容,以使用名为 "TLSv1.1" 的 SSL 配置。这个连接似乎使用的是 TLSv1 协议。因此,由于协议不匹配,连接失败。似乎此 SSL 配置不打算用于访问 127.0.0.1 和端口 9202。这可能是您的本地节点代理或 dmgr 端口吗?如果是这样,连接需要 NodeDefaultSSLSettings。
在跟踪中,我看不出什么连接正在与您的服务器、本地主机和端口 1234 通信。也许如果您修复您的配置,以便节点在转到端口 9202 和 127.0 时将使用正确的 SSL 配置。 0.1 可能更容易算出来。
感谢您的大力支持&swift回复! 根据您的输入,我删除了 SSL 配置设置中存在的所有动态出站规则。
我也修改了支持的密码套件列表 在 WAS 端(客户端),基于您提供的 link!:-)。 更准确地说,我只选择了这些套房 因为所有 TLS 协议(TLSv1.0、TLSv1.1、TLSv1.2)都支持它们:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
我再次清除了所有日志文件,然后启动了应用程序服务器。 重新测试我的方案后,已生成日志文件中的此增量: https://drive.google.com/open?id=19KaDlsx2UVS_YfByaORQOf89mLlJke4e
监听1234端口的服务端应用同样支持 密码套件:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
当然没想到改完之后问题就解决了 但我预计我会在 logs/traces 中发现一些错误,以减轻强加给您的负担。不幸的是,我没有成功。你能检查一下这些 logs/traces 吗?非常感谢!
(请忽略此异常:
FFDC Exception:java.net.MalformedURLException SourceId:class com.ibm.wkplc.extensionregistry.PluginDescriptor.initFromDom ProbeId:1
存在于 server1_b7f67871_17.12.19_04.44.51.8551967663872103714940.txt 文件中, 因为我再次重新测试它(第 3 次)并且在第 3 次重新测试后没有出现此异常。)
所以由于我最初没有仔细查看您的代码。我看到了问题。因为您直接从 JSSEHelper 获取套接字工厂,所以我们没有机会将密码放在套接字上。
在您的情况下,您应该遵循 WAS 的编程 SSL 方法。获取属性并将它们放在线程上。例如
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() 中做类似的事情:
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 套接字工厂。创建套接字调用应该 return 为您提供一个在 SSLSocket 上设置了密码的套接字。完成后,您应该清除线程中的属性。
jsseHelper.setSSLPropertiesOnThread(null);