自签名证书的 HttpClient 4.1.x 错误(javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated ) [英] HttpClient 4.1.x error for self signed certificate (javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated )
问题描述
我正在尝试使用 clientAuth=true & 的自签名证书配置 Tomcat6然后使用 HttpClient 4.1.x 在客户端调用 Tomcat 服务器.
I am trying to configure the Tomcat6 with self-signed certificates with clientAuth=true & then to call the Tomcat server on client side using HttpClient 4.1.x.
我按照 http://virgo47.wordpress.com/2010/08/23/tomcat-web-application-with-ssl-client-certificates/ &当我从浏览器或 openssl 客户端进行测试时,它按预期工作正常(我运行了命令openssl s_client -cert client.crt -key client.key -CAfile ca.crt -connect localhost:8443").
I followed the instruction provided in the http://virgo47.wordpress.com/2010/08/23/tomcat-web-application-with-ssl-client-certificates/ & it is working fine as expected when I am testing from the browser or from the openssl client (I ran the command "openssl s_client -cert client.crt -key client.key -CAfile ca.crt -connect localhost:8443").
我面临的问题是 HttpClient.我写了下面的代码来创建HttpClient
The problem I am facing is with the HttpClient. I wrote the following code to create HttpClient
private DefaultHttpClient creatHttpClient(KeyStore keyStore,
char[] keyStorePassword, KeyStore trustStore, char[] trustStorePassword) {
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore); // This contains CA certs
TrustManager[] tm = trustManagerFactory.getTrustManagers();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePassword); // This contain client private key
KeyManager[] km = keyManagerFactory.getKeyManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(km, tm, new SecureRandom());
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(sslContext,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 30000);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https",
443, sslSocketFactory));
ClientConnectionManager clientConnectionManager =
new ThreadSafeClientConnManager(schemeRegistry);
final DefaultHttpClient httpClient = new DefaultHttpClient(
clientConnectionManager, params);
return httpClient;
} catch(Exception e) {
throw e;
}
}
为此,我收到了
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
我启用了调试
static
{ System.setProperty("javax.net.debug", "ssl,handshake,trustmanager"); }
我收到以下调试日志
main, handling exception: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
main, SEND TLSv1 ALERT: fatal, description = internal_error
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, IOException in getSession(): javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
main, called close()
main, called closeInternal(true)
main, called close()
main, called closeInternal(true)
在这种情况下可能会出现什么问题?我不想忽略 ssl 证书错误,而是想正确进行身份验证.
What could be possibly going wrong in this case? I don't want to ignore the ssl certificates error rather want to authenticate properly.
推荐答案
我自己解决了问题.问题是我正在加载密钥库 &信任存储使用
I solved my own problem. The issue was that I was loading keystore & trust store using
InputStream ksin = this.getClass().getResourceAsStream("client.jks");
InputStream tsin = this.getClass().getResourceAsStream("cacerts.jks");
&在 Junit 测试中使用这些行它无法找到 .jks 文件.
& was using these lines in the Junit tests & it was not able to find .jks files.
我通过输入以下内容发现了这一点
I figured out this by putting the following
if(0 == keyStore.size()) { throw new RuntimeException("Keystore is empty"); }
if(0 == trustStore.size()) { throw new RuntimeException("Truststore is empty"); }
在密钥库之后 &信任库初始化.
after keystore & truststore initialization.
所以,我将行改为
InputStream ksin = Thread.currentThread().getContextClassLoader().getResourceAsStream("client.jks");
InputStream tsin = Thread.currentThread().getContextClassLoader().getResourceAsStream("cacerts.jks");
&一切正常.
这篇关于自签名证书的 HttpClient 4.1.x 错误(javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated )的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!