首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 6 HTTPS客户端证书认证

Java 6 HTTPS客户端证书认证
EN

Stack Overflow用户
提问于 2013-08-01 07:15:38
回答 1查看 3.7K关注 0票数 2

我尝试在java6u45上使用带有URLConnection的客户端证书身份验证,它返回400个HTTP代码,但是当我用java 7u25构建相同的证书时,它工作得很好,并返回OK 200。

当我尝试Apache HttpPost时,它给出了6u 45和7u 25的400个错误。

代码语言:javascript
复制
C:\java\test>"C:\Program Files (x86)\Java\jdk1.6.0_45\bin\javac" Test.java -cp ".;lib/*"

C:\java\test>"C:\Program Files (x86)\Java\jdk1.6.0_45\bin\java" -cp ".;lib/*" Test
Response Code 1: 400
Response Code 2: 400

C:\java\test>"C:\Program Files (x86)\Java\jdk1.7.0_25\bin\javac" Test.java -cp ".;lib/*"

C:\java\test>"C:\Program Files (x86)\Java\jdk1.7.0_25\bin\java" -cp ".;lib/*" Test
Response Code 1: 200
Response Code 2: 400

我相信让它在java 6上工作是相当容易的,至少在Apache上是这样,但是我做了一些错误的事情。

我的测试代码如下:

代码语言:javascript
复制
import java.io.*;
import java.net.*;
import java.security.*;
import javax.net.ssl.*;
import org.apache.http.*;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.*;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.params.*;
import org.apache.http.entity.StringEntity;

public class Test {
    public static void main(String[] args) {
        String keyStorePath = "C:\\java\\keys\\client_certificate.p12";
        String keyStorePass = "someKeyStorePass";
        String trustStorePath = "C:\\java\\keys\\truststore.jks";
        String trustStorePass = "someTrustStorePath";
        String postData = "<request></request>";
        String url = "https://api.some-url.com/v2";

        SSLContext sslContext = GetSSLContext(keyStorePath, keyStorePass, trustStorePath, trustStorePass);
        PostData1(postData, url, sslContext);

        SchemeRegistry schemeRegistry = GetSchemeRegistry(keyStorePath, keyStorePass, trustStorePath, trustStorePass);
        PostData2(postData, url, schemeRegistry);
    }

    public static void PostData1(String dataToPost, String serviceUrl, SSLContext sslContext) {
        try {
            URL url = new URL(serviceUrl);

            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            HttpsURLConnection urlConn = (HttpsURLConnection)url.openConnection();
            urlConn.setDoOutput(true);
            urlConn.setDoInput(true);
            urlConn.setUseCaches(false);
            urlConn.setRequestMethod("POST");
            urlConn.setRequestProperty("Content-Type", "application/xml");
            urlConn.connect();

            PrintWriter out = new PrintWriter(urlConn.getOutputStream());
            out.println(dataToPost);
            out.close();

            System.out.println("Response Code 1: " + urlConn.getResponseCode());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void PostData2(String dataToPost, String serviceUrl, SchemeRegistry schemeRegistry) {
        try {
            HttpParams httpParams = new BasicHttpParams();
            DefaultHttpClient httpClient = new DefaultHttpClient(new BasicClientConnectionManager(schemeRegistry), httpParams);

            HttpPost httpPost = new HttpPost(serviceUrl);

            HttpEntity lEntity = new StringEntity(dataToPost, "UTF-8");
            httpPost.setEntity(lEntity);

            HttpResponse response = httpClient.execute(httpPost);

            try {
                System.out.println("Response Code 2: " + response.getStatusLine().getStatusCode());
            } finally {
                httpPost.releaseConnection();
            }

            httpClient.getConnectionManager().shutdown();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static SSLContext GetSSLContext(String clientStorePath, String clientStorePass, String trustStorePath, String trustStorePass) {
        SSLContext sslContext = null;

        try {
            KeyStore clientStore = KeyStore.getInstance("PKCS12");
            clientStore.load(new FileInputStream(clientStorePath), clientStorePass.toCharArray());

            KeyManagerFactory kmf =KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientStore, clientStorePass.toCharArray());
            KeyManager[] kms = kmf.getKeyManagers();

            KeyStore trustStore = KeyStore.getInstance("JKS");
            trustStore.load(new FileInputStream(trustStorePath), trustStorePass.toCharArray());

            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(trustStore);
            TrustManager[] tms = tmf.getTrustManagers();

            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(kms, tms, new SecureRandom());

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return sslContext;
    }

    public static SchemeRegistry GetSchemeRegistry(String clientStorePath, String clientStorePass, String trustStorePath, String trustStorePass) {
        final SchemeRegistry schemeRegistry = new SchemeRegistry();

        try {
            KeyStore clientStore = KeyStore.getInstance("PKCS12");
            clientStore.load(new FileInputStream(clientStorePath), clientStorePass.toCharArray());

            KeyStore trustStore = KeyStore.getInstance("JKS");
            trustStore.load(new FileInputStream(trustStorePath), trustStorePass.toCharArray());

            schemeRegistry.register(new Scheme("https", 443, new SSLSocketFactory(clientStore, clientStorePass, trustStore)));

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return schemeRegistry;
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-19 15:33:25

通过对HTTPS协议流量的深入研究,我发现Java6不支持SNI,并且这个特性仅在Java 7中添加。

我的Nginx服务器在同一个IP上有几个HTTPS VirtualHosts,而且由于Java6没有传递确切的主机名,所以返回了默认主机。

要解决这个问题,只需将您的VirtualHost标记为默认的客户端身份验证:

代码语言:javascript
复制
listen xxx.xxx.xxx.xxx:443 default;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17987463

复制
相关文章

相似问题

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