我正在尝试使用在WAS 8.0.0.13(使用java 1.6.0的IBM Websphere应用程序服务器)中配置的CUSTOM出站ssl配置以编程方式创建SSL连接: (安全 - > SSL证书和密钥管理 - >相关项目:SSL配置)。 已成功创建安全连接:驻留在WAS服务器上的servlet已连接到侦听127.0.0.1:1234的服务器端套接字。 问题是我的首选密码套件是在“保护质量(QoP)设置”中定义的。 SSL配置中的内容将被忽略。 所有其他属性(例如协议或JSSE提供者)都被很好地看待。
我已经实现了一个Servlet,它是一个SSL客户端。 此Servlet使用此自定义SSL配置,该配置定义了以下密码套件:
不幸的是,ClientHello请求中提供了不同的密码套件列表:
(此自定义SSL配置在其定义中包含TLSv1.1协议。)
我还尝试了另一种具有较小密码套件的协议(TLSv1.2):
ClientHello请求中再次提供了一个不同的密码套件列表:
此外,我还检查了cell-default密码套件和node-default-cipher-suites,但没有 它们与ClientHello中提供的匹配: 默认节点配置/默认单元配置:
并创建了以下实现。 '的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配置的东西。
答案 0 :(得分:1)
因为我最初没有仔细查看你的代码。我看到了问题。因为您直接从JSSEHelper获取Socket工厂,所以我们没有机会将密码放在套接字上。
在您的情况下,您应该遵循WAS的编程SSL方法。获取属性并将它们放在线程上。例如
cout
后者没有从JSSE获得Socket工厂,获得默认值。所以在getSslSocket()中执行类似的操作:
try {
String existingAlias = "TLSv1.1";
existing_sslProps = jsseHelper.getProperties(existingAlias);
jsseHelper.setSSLPropertiesOnThread(existing_sslProps);
} catch (com.ibm.websphere.ssl.SSLException e) {
e.printStackTrace();
}
这将为您提供WAS套接字工厂。创建套接字调用应该返回一个套接字,其中包含在SSLSocket上设置的密码。完成后,您应该清除线程中的属性。
public SSLSocket getSslSocket(Properties sslProps) {
SSLSocketFactory factory = SSLSocketFactory.getDefault();
SSLSocket socket = null;
try {
socket = (SSLSocket) factory.createSocket();
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
答案 1 :(得分:0)
谢谢你的提示!我按照这些说明操作:
https://www-01.ibm.com/support/docview.wss?uid=swg21162961
根据您的提示增加日志/跟踪级别。 如果我必须更改其他配置,请告诉我。
我只收集了这些子目录中的日志文件:
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
我不确定是否是我的问题的根本原因,但谷歌搜索结果似乎与我的问题无关。 就谷歌的结果而言,我的意思是:
http://www.dsxchange.com/viewtopic.php?t=134492&sid=f6e236a4f14a9d80fc51c0820e5f7ce7 他们都没有帮助......
与logs-subdirectories一起,我还在TLSv1.1_enforce_OnThread.log中附加了stderr的服务器端套接字stdout。 另外,我还附加了客户端配置CONFIG_TLSv1.1._ENFORSE_SSL_ON_THREAD.png
您能检查一下这些日志文件吗? 老实说,非常感谢你。
- 迈克尔
答案 2 :(得分:0)
我正在查看涉及使用名为“TLSv1.1”的SSL配置的错误。 TLSv1.1不支持您配置的3个密码中的2个,您可以在此处找到有关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]
此连接将在同一主机127.0.0.1上发送到端口9202。并最终以错误结束,javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure。我认为您的服务器正在尝试使用错误的SSL配置与您的nodeagent通信。它似乎从动态出站选择过滤器中选择了该配置。
[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。
在跟踪中,与您的服务器,localhost和端口1234进行通信的连接并不明显。或许,如果您修改了配置,以便在转到端口9202和127.0.0.1时节点将使用正确的SSL配置可能更容易理解。
答案 3 :(得分:0)
感谢您的大力支持和支持机智的回复! 根据您的输入,我删除了SSL配置设置中存在的所有动态出站规则。
我还修改了支持的密码套件列表 在WAS端(客户端)基于您提供的很棒的链接!:-)。 更确切地说,我选择了这些套房 因为所有TLS协议(TLSv1.0,TLSv1.1,TLSv1.2)都支持它们:
再次,我清除了所有日志文件,然后启动了应用程序服务器。 重新测试我的方案后,已生成日志文件中的此增量: https://drive.google.com/open?id=19KaDlsx2UVS_YfByaORQOf89mLlJke4e
侦听1234端口的服务器端应用程序支持相同 密码套件:
当然,我没想到在这些变化之后问题会得到解决 但我希望我在日志/跟踪中发现一些错误,以减轻你的负担。不幸的是,我没有成功。你能检查一下这些日志/痕迹吗?老实说,非常感谢你!
(请忽略此例外:
FFDC异常: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次重新测试后没有出现这种异常。)