- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正尝试通过 SSL
从 tomee 1.6 服务器
调用 WS
,但我收到了 SSLHandshakeError
。问题是证书是自签名的,我的 JVM
无法识别。由于它仅用于测试目的,而不是生产目的,因此我被要求绕过证书控制。我阅读了很多关于如何进行的资料,并且我已经编写了代码:
NaiveSSLContext 类:
package fr.csf.ssl;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* A factory class which creates an {@link SSLContext} that
* naively accepts all certificates without verification.
*/
public class NaiveSSLContext
{
private NaiveSSLContext()
{}
/**
* Get an SSLContext that implements the specified secure
* socket protocol and naively accepts all certificates
* without verification.
*/
public static SSLContext getInstance( String protocol) throws NoSuchAlgorithmException
{
SSLContext sslCtx = SSLContext.getInstance( protocol);
init( sslCtx);
return sslCtx;
}
/**
* Get an SSLContext that implements the specified secure
* socket protocol and naively accepts all certificates
* without verification.
*/
public static SSLContext getInstance( String protocol, Provider provider) throws NoSuchAlgorithmException
{
SSLContext sslCtx = SSLContext.getInstance( protocol, provider);
init( sslCtx);
return sslCtx;
}
/**
* Get an SSLContext that implements the specified secure
* socket protocol and naively accepts all certificates
* without verification.
*/
public static SSLContext getInstance( String protocol, String provider) throws NoSuchAlgorithmException, NoSuchProviderException
{
SSLContext sslCtx = SSLContext.getInstance( protocol, provider);
init( sslCtx);
return sslCtx;
}
/**
* Set NaiveTrustManager to the given context.
*/
private static void init( SSLContext context)
{
try
{
// Set NaiveTrustManager.
context.init( null, new TrustManager[] { new NaiveTrustManager() }, new java.security.SecureRandom());
System.out.println( "------------- Initialisation du NaiveSSLContext ---------------------");
}
catch( java.security.KeyManagementException e)
{
throw new RuntimeException( "Failed to initialize an SSLContext.", e);
}
}
/**
* A {@link TrustManager} which trusts all certificates naively.
*/
private static class NaiveTrustManager implements X509TrustManager
{
@Override
public X509Certificate[] getAcceptedIssuers()
{
System.out.println( "------------- NaiveTrustManager.getAcceptedIssuers() ---------------------");
return null;
}
@Override
public void checkClientTrusted( X509Certificate[] certs, String authType)
{
System.out.println( "------------- NaiveTrustManager.checkClientTrusted( " + certs.toString() + ", " + authType
+ ") ---------------------");
}
@Override
public void checkServerTrusted( X509Certificate[] certs, String authType)
{
System.out.println( "------------- NaiveTrustManager.checkServerTrusted( " + certs.toString() + ", " + authType
+ ") ---------------------");
}
}
}
和另一个类NaiveSSLSocketFactory:
package fr.csf.ssl;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
public class NaiveSSLSocketFactory extends javax.net.ssl.SSLSocketFactory
{
private javax.net.ssl.SSLSocketFactory factory;
public NaiveSSLSocketFactory() throws NoSuchAlgorithmException
{
javax.net.ssl.SSLContext sslCtx = NaiveSSLContext.getInstance( "SSL");
factory = sslCtx.getSocketFactory();
}
private final String[] enabledProtocols = new String[]
{ "SSLv3", "TLSv1" };
@Override
public Socket createSocket( Socket s, String host, int port, boolean autoClose) throws IOException
{
Socket socket = factory.createSocket( s, host, port, autoClose);
((javax.net.ssl.SSLSocket) socket).setEnabledProtocols( enabledProtocols);
return socket;
}
@Override
public Socket createSocket( String host, int port) throws IOException, UnknownHostException
{
Socket socket = factory.createSocket( host, port);
((javax.net.ssl.SSLSocket) socket).setEnabledProtocols( enabledProtocols);
return socket;
}
@Override
public Socket createSocket( InetAddress host, int port) throws IOException
{
Socket socket = factory.createSocket( host, port);
((javax.net.ssl.SSLSocket) socket).setEnabledProtocols( enabledProtocols);
return socket;
}
@Override
public Socket createSocket( String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException
{
Socket socket = factory.createSocket( host, port, localHost, localPort);
((javax.net.ssl.SSLSocket) socket).setEnabledProtocols( enabledProtocols);
return socket;
}
@Override
public Socket createSocket( InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
{
Socket socket = factory.createSocket( address, port, localAddress, localPort);
((javax.net.ssl.SSLSocket) socket).setEnabledProtocols( enabledProtocols);
return socket;
}
@Override
public String[] getDefaultCipherSuites()
{
String[] cipherSuites = factory.getDefaultCipherSuites();
return cipherSuites;
}
@Override
public String[] getSupportedCipherSuites()
{
String[] cipherSuites = factory.getSupportedCipherSuites();
return cipherSuites;
}
}
问题是我无法找到如何让 JVM 使用我的 Naive* 类而不是默认类。我尝试了不同的方法,但它们都不起作用:
第一次尝试:
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory( new NaiveSSLSocketFactory());
我在 checkClientTruted 方法中的日志跟踪从未显示。似乎从未调用过我的 NaiveSSLSocketFactory。
第二次尝试:
java.security.Security.setProperty( "ssl.SocketFactory.provider", new NaiveSSLSocketFactory().getClass().getName());
由于 ClassLoader 问题,我遇到了 ClassNotFoundException,但在修复此问题后,同样的问题仍然存在。
我最终找到了一篇博客,其中说 CXF 客户端必须做一些更多的配置工作:
<http-conf:conduit name="*.http-conduit" >
<http-conf:tlsClientParameters
useHttpsURLConnectionDefaultSslSocketFactory="true"
/>
</http-conf:conduit>
由于我使用的是Tomee1.6服务器,我的程序是CXF客户端。所以这必须是解决方案。但是我必须在哪里写这个配置属性?我在 Tomee 中找不到任何与 CXF 相关的 xml 文件。只有 cxf.properties 文件,几乎是空的。
最佳答案
首先,Tomcat 不参与您对 Web 服务的使用 - 事实上,它实际上不参与您的应用程序正在建立的任何出站连接。
我知道有两种方法可以实现 CXF 提供的预期结果,并且不会影响在同一 JVM 上运行的任何其他出站 SSL 连接:
第一种方法更可取,因为第二种方法将信任您的客户端连接的任何端点。
要实现第一种方法,请创建一个包含您希望信任的证书的 keystore (并且最好包括任何中间证书)。然后按照 CXF 手册部分 Configuring SSL Support 中的概述添加此信任库.您的管道配置将如下所示:
<http:conduit name="{http://apache.org/hello_world}HelloWorld.http-conduit">
<http:tlsClientParameters>
<sec:trustManagers>
<sec:keyStore type="JKS" password="password"
file="my/file/dir/Truststore.jks"/>
</sec:trustManagers>
</http:tlsClientParameters>
<http:client AutoRedirect="true" Connection="Keep-Alive"/>
</http:conduit>
请注意,上面示例中的管道名称显然只是一个示例。参见 the update to my answer here关于如何指定管道名称的另一个问题。另请注意,我没有包含密码套件过滤器,因为我相信它会默认为某些值集,如果您使用的是 Java 6 或更早版本,这可能是不安全的……但那是另一个话题。
此外,您可以完全避开 CXF 的 Spring 配置,并使用 CXF 客户端 API 以编程方式执行上述所有操作。
我还强烈建议使用像 KeyStore Explorer 这样的工具从目标端点提取证书(和中介)并将它们导入到新的信任库中。
最后,关于您的初始解决方案,我想指出在 JVM 范围内安装诸如 SSL 套接字工厂和受 JDK API 支持的信任管理器之类的东西的危险。在支持多个应用程序的容器内运行时,这样做可能会产生危险的后果:您可能会破坏其他应用程序的安全配置文件。使用像 CXF 这样的框架的好处之一是它提供了为每个应用程序客户端(或服务器)实例自定义 SSL/TLS 配置的方法。
关于java - 如何使用 Tomee 绕过 Https SSLHandshakeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33434045/
在日志中看到此错误消息,任何人都可以告诉发生了什么 “javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorExcep
我获得了一个 jar 文件,但无法访问代码(或无法修改)和一个 .cer ca 证书文件。 运行jar文件时;我收到此错误(我输入了 placeholder.hostname.com ): org.s
我需要忽略 PKIX 路径构建异常 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PK
我正在尝试使用 HttpsURLConnection 与网站建立 HTTPS 连接,然后执行 PUT 请求。当我尝试从 HttpsURLConnection.getOutputStream() 创建
我的 SSL 握手有一个小问题,当我尝试启动 GET 请求时,服务器返回 java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException
非常感谢您阅读这篇文章,我们将不胜感激! 我正在尝试使用服务帐户在云端硬盘中列出和创建一个文本文件。已经生成了一个服务帐户,下载了 p12 文件也为该帐户启用了 Drive api。但是我收到了 SS
我使用 Retrofit2。添加服务器端 SSL 后请求不会执行。 onFailure 方法获取下一个 Throwable - javax.net.ssl.SSLHandshakeException:
这个问题在这里已经有了答案: Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorExce
我正在尝试使用自签名证书访问本地 https 站点。我修改了主机文件并为我的本地站点分配了一个 IP 地址;我用来访问网站的代码: String httpsURL = "https://test-s
我有一个服务到服务的连接,它间歇性地从 Jersey 客户端抛出 SSLHandshakeExceptions。 public static class MyClientFilter extends
我正在尝试创建端点以将我的谷歌应用引擎连接到我的 android 应用程序。我正在学习本教程 https://developers.google.com/eclipse/docs/endpoints-
使用这样的代码: val html = Source.fromURL("https://scans.io/json") 获取异常: Exception in thread "main" javax.n
我正在尝试从 Java 9 测试新的 HttpClient。出于测试目的,我正在使用 https://jsonplaceholder.typicode.com 提供的 api。 .但是,我收到握手异常
我正在寻找类似于 this answer 的解决方案,但更安全。我想禁用证书验证,但仅针对单个请求(这就是我所需要的)。所以它应该做以下一项或多项 完成一个请求后返回安全状态 仅对给定的 URL 禁用
当我访问 wsdl url 时,我在 android 中遇到异常 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathVal
当我尝试使用 Java 代码以编程方式下载文件时,出现异常: Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.s
我们有一个 JavaFX 应用程序在 https 安全资源上调用我们的后端。该应用程序连续向同一个 url 发出数百个请求,以从服务器获取数据。 这通常没有问题,但现在我们有一个客户在连接到资源时报告
我正在尝试从 java 访问我的 api,但出现以下错误: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate
我最近在我的网站上添加了 SSL,可以通过 https 访问它。现在,当我的 Java 应用程序尝试向我的网站发出请求并使用缓冲读取器从中读取时,它会生成此堆栈跟踪 我没有使用自签名证书,该证书来自
我有两个代码示例,一个使用 Rest Template 和其他 Apache HttpClient 将 json 发布到我们的内部 https Web 服务。 我们的服务负载均衡器端存在这个已知的 S
我是一名优秀的程序员,十分优秀!