首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >基于HTTPS/SSL的Java客户端证书

基于HTTPS/SSL的Java客户端证书
EN

Stack Overflow用户
提问于 2009-05-17 20:51:55
回答 7查看 439.5K关注 0票数 121

我正在使用Java6,并尝试使用客户端证书在远程服务器上创建一个HttpsURLConnection

服务器正在使用自签名根证书,并要求提供受密码保护的客户端证书。我已经将服务器根证书和客户端证书添加到我在/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts (OSX10.5)中找到的默认java密钥库。密钥库文件的名称似乎表明客户端证书不应该放在其中?

总之,将根证书添加到此存储解决了臭名昭著的javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed' problem.

但是,我现在遇到了如何使用客户端证书的问题。我尝试了两种方法,但都没有成功。

首先,也是首选的,尝试:

代码语言:javascript
复制
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://somehost.dk:3049");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
// The last line fails, and gives:
// javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

我尝试跳过HttpsURLConnection类(不是很理想,因为我想和服务器对话),而是这样做:

代码语言:javascript
复制
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("somehost.dk", 3049);
InputStream inputstream = sslsocket.getInputStream();
// do anything with the inputstream results in:
// java.net.SocketTimeoutException: Read timed out

我甚至不确定客户端证书是不是这里的问题。

EN

回答 7

Stack Overflow用户

发布于 2009-05-18 08:58:31

虽然不建议这样做,但您也可以一起禁用SSL证书验证:

代码语言:javascript
复制
import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

public class SSLTool {

  public static void disableCertificateValidation() {
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] { 
      new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() { 
          return new X509Certificate[0]; 
        }
        public void checkClientTrusted(X509Certificate[] certs, String authType) {}
        public void checkServerTrusted(X509Certificate[] certs, String authType) {}
    }};

    // Ignore differences between given hostname and certificate hostname
    HostnameVerifier hv = new HostnameVerifier() {
      public boolean verify(String hostname, SSLSession session) { return true; }
    };

    // Install the all-trusting trust manager
    try {
      SSLContext sc = SSLContext.getInstance("SSL");
      sc.init(null, trustAllCerts, new SecureRandom());
      HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
      HttpsURLConnection.setDefaultHostnameVerifier(hv);
    } catch (Exception e) {}
  }
}
票数 84
EN

Stack Overflow用户

发布于 2009-05-17 22:42:21

是否设置了KeyStore和/或TrustStore系统属性?

代码语言:javascript
复制
java -Djavax.net.ssl.keyStore=pathToKeystore -Djavax.net.ssl.keyStorePassword=123456

或使用代码从

代码语言:javascript
复制
System.setProperty("javax.net.ssl.keyStore", pathToKeyStore);

与javax.net.ssl.trustStore相同

票数 21
EN

Stack Overflow用户

发布于 2010-07-08 05:42:54

如果您正在使用Axis框架处理web服务调用,则有一个简单得多的答案。如果您的客户端希望能够调用SSL web服务并忽略SSL证书错误,则只需在调用任何web服务之前输入以下语句:

System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory");

通常的免责声明是在生产环境中做一件非常糟糕的事情。

我在the Axis wiki找到了这个。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/875467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档