我知道浏览器和java7之所以不受影响,是因为它们将服务器名称指示SNI作为SSL信息的一部分发送。因此,apache在启动SSL握手之前知道要使用哪个虚拟主机,并返回正确的证书。Java6不支持SNI。所以我的问题是,如何在Java6中验证并允许证书被接受。
我制作了一个spring客户端来使用webservice,下面是我的代码
public class classname1 {
static {
System.setProperty("javax.net.ssl.trustStore", "E://Workspace//keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("https.protocols", "SSLv3");
System.setProperty("https.protocols", "TLSv1");
}
static {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
public boolean verify(String hostname, SSLSession session)
{
if (hostname.equals("192.168.10.22"))
return true;
return false;
}
});
}
private static void main(String[] args) {
try {
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
String url = "https://192.168.10.22/getInformationSearch.asmx?wsdl";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
printSOAPResponse(soapResponse);
soapConnection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest() throws Exception {
// ... Code for request, which will be hitted to url
}
private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
// ... Code for response, which will fetch information from webservice
// URL
}
}
正如您看到的代码,我创建了两个方法,1。对于请求createSOAPRequest()
2。对于响应printSOAPResponse()
。(Url名称在上述代码段中已更改)
在main()
方法中,下面的行将生成请求并将该请求发送到给定的url SOAPMessage soapResponse=soapConnection。调用(createSOAPRequest(),url)
之后进入静态块,如上图所示
HttpsURLConnection。setDefaultHostnameVerifier()
方法。
当时,调试器说:ssl握手失败,ssl对等机错误地关闭。这只发生在Java6中,但这些代码在Java7/8中正常工作。
我尝试了以下java 6中的代码,而不是静态块
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName,
SSLSession session) {
return true;
}
};
但无论如何都不行!!!
我正在使用以下JAR xercesImpl。jar,saajapi。jar,saaj impl。jar,spring-ws-core-1.5.6。jar,spring-ws-security-1.5.6。这个SSL域的jar和证书已经导入密钥库,它在java7/8中工作,所以truststore中没有问题,对吗?(我也使用Java6和java7的keytool制作了2个证书,这两个证书在java7/8中都可以正常工作,但在6中却不行)
我跟着这条线走,但它不起作用。那么,有没有其他方法来验证证书并在java 6环境中获得响应,或者我应该更改任何JAR?
正如您已经提到的Java6不支持SNI。但是,缺少SNI的问题不仅在于验证证书(因为服务器发送了错误的证书),而且取决于服务器的配置,如果SNI扩展不存在并且不指向主机名,服务器将导致握手错误在服务器上可用。这里显然是这样:
... ssl握手失败,SSL对等端关闭不正确。它只发生在JAVA 6中,但是这些代码在java 7/8中正常工作。
在这种情况下,尝试更改证书的验证将毫无帮助,因为错误甚至在客户端有证书要验证之前就发生了。这意味着没有办法绕过它:如果您想与此特定服务器通信,您需要支持客户端中的SNI。
如果服务器未配置为允许您在没有SNI的情况下进行连接,则无法连接。
如果没有SNI,服务器在建立SSL连接之前无法确定您想要的虚拟主机。
如果您有OpenSSL,您可以使用s_client
选项来提取不同的证书,或者在不使用SNI时注意连接失败:
SNI:
echo | openssl s_client -servername www.virtualhost.com -connect 192.168.1.55:443 | openssl x509 -text
用服务器的实际IP地址替换192.168.1.55
,并www.virtualhost。com
,其中包含要连接到的虚拟主机的主机名。管道前面的echo
命令可防止openssl
在等待输入时挂起。
没有SNI:
echo | openssl s_client -connect 192.168.1.55:443 | openssl x509 -text
如果没有SNI,您可能会看到一个完全不同的证书,或者您可能会遇到连接错误。
问题内容: 在golang中,始终将JSON消息中的数字解析为float64。为了检测它是否实际上是整数,我正在检查其类型。不幸的是,没有常数代表。 有没有更优雅的解决方案,而不是使用0或0.0来获取? 问题答案: 您也可以在类型的文档上使用或方法,其可能的值在程序包中作为常量列出。 您也可以在中使用它: 请注意,和都有一个方法,因此,如果您以和开头,都可以使用它。
授权服务器可以支持任何与其安全要求匹配的合适的HTTP身份验证方案。当使用其他身份验证方法时,授权服务器必须定义客户端标识(注册记录)和认证方案之间的映射。
问题内容: 根据Java 7文档以及第三方供应商的说法,似乎Java 7应该支持AES-GCM套件: IBM Java 7 Java 7 SSL文档 在客户端和服务器之间的协商中遇到一些错误,由于仅将其限制为AES- GCM密码而无法协商密码。经过调查,我发现客户端或服务器(tomcat实例)均不支持密码套件。在客户端上运行一些示例代码以获取输出: 不知道是否有人遇到过这样的问题。 Java 7是
我已经在Netty中尝试了双向SSL身份验证 但这个例子不再显示任何信息,只是一个404未找到。我在这里找到了一些帮助: https://github.com/code4craft/netty-learning/blob/master/netty-3.7/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFac
问题内容: 我想测试一些在同一类中调用其他方法的方法。它们基本上是相同的方法,但是具有不同数量的参数,因为数据库中有一些默认值。我在这个上展示 因此,我想测试在调用方法getPrice(int)时是否调用了方法getPriceForOne()。基本上像平常一样调用getPrice(int)并模拟getPriceForOne。 请记住,我有一个更为复杂的文件,该文件可供其他人使用,它们必须全部放在一
我正在使用WebSphere Liberty 19.0.0.2和WebProfile-8.0特性,该特性支持JAXRS-2.1和BeanValidation-2.0。为了更好地支持多部分流,我使用Jersey作为JAX-RS实现,而不是Liberty的默认Apache CXF。 有关相关组件版本控制的一些更多上下文信息 Bean验证1.1(JSR 349)、Bean验证2.0(JSR 380) 下