(Java)未发送所需的SSL证书(在curl调用中使用时工作正常)

(Java)未发送所需的SSL证书(在curl调用中使用时工作正常),java,ssl,ssl-certificate,client-certificates,Java,Ssl,Ssl Certificate,Client Certificates,因此,我试图通过在Java程序中使用客户端证书来测试与我公司的web服务器的连接(使用双向SSL)。 我尝试在curl调用中使用相同的证书(证书和密钥分开),并设法得到所需的响应。 但是,当我尝试在Java程序中使用它(组合成pkcs12格式)时,它给出了一个400响应,表示没有发送所需的SSL证书。为什么会这样 public static void main(String[] args) { System.out.println("Taufiq's mutual SSL-authent

因此,我试图通过在Java程序中使用客户端证书来测试与我公司的web服务器的连接(使用双向SSL)。 我尝试在curl调用中使用相同的证书(证书和密钥分开),并设法得到所需的响应。 但是,当我尝试在Java程序中使用它(组合成pkcs12格式)时,它给出了一个400响应,表示没有发送所需的SSL证书。为什么会这样

public static void main(String[] args) {
    System.out.println("Taufiq's mutual SSL-authentication test");
    org.apache.log4j.BasicConfigurator.configure();
    Logger.getRootLogger().setLevel(Level.INFO);

    try {
        final String CERT_ALIAS = "something", CERT_PASSWORD = "something";

        KeyStore identityKeyStore = KeyStore.getInstance("pkcs12");
        FileInputStream identityKeyStoreFile = new FileInputStream(new File("src/Cert.p12"));
        identityKeyStore.load(identityKeyStoreFile, CERT_PASSWORD.toCharArray());

        KeyStore trustKeyStore = KeyStore.getInstance("jks");
        FileInputStream trustKeyStoreFile = new FileInputStream(new File("src/truststore.jks"));
        trustKeyStore.load(trustKeyStoreFile, CERT_PASSWORD.toCharArray());

        SSLContext sslContext = SSLContexts.custom()
            // load identity keystore
            .loadKeyMaterial(identityKeyStore, CERT_PASSWORD.toCharArray(), new PrivateKeyStrategy() {
                @Override
                public String chooseAlias(Map<String, PrivateKeyDetails> aliases, Socket socket) {
                    return CERT_ALIAS;
                }
            })
            // load trust keystore
            .loadTrustMaterial(trustKeyStore, null)
            .build();

        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
            new String[]{"TLSv1.2", "TLSv1.1"},
            null,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());

        CloseableHttpClient client = HttpClients.custom()
            .setSSLSocketFactory(sslConnectionSocketFactory)
            .build();

        // Call a SSL-endpoint
        callEndPoint (client);
    } catch (Exception ex) {
        System.out.println("Boom, we failed: " + ex);
        ex.printStackTrace();
    }
}

private static void callEndPoint(CloseableHttpClient aHTTPClient) {

    try {          
        String ServerUrl = "My Company URL";
        System.out.println("Calling URL: " + ServerUrl);
        HttpPost post = new HttpPost(ServerUrl);
        post.setHeader("Content-type", "application/json");

        System.out.println("**POST** request Url: " + post.getURI());

        HttpResponse response = aHTTPClient.execute(post);

        int responseCode = response.getStatusLine().getStatusCode();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Content:-\n");
        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        String line;
        while ((line = rd.readLine()) != null) {
            System.out.println(line);
        }
    } catch (Exception ex) {
        System.out.println("Boom, we failed: " + ex);
        ex.printStackTrace();
    }

}
publicstaticvoidmain(字符串[]args){
System.out.println(“Taufiq的相互SSL认证测试”);
org.apache.log4j.BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.INFO);
试一试{
最后一个字符串CERT\u ALIAS=“something”,CERT\u PASSWORD=“something”;
KeyStore identityKeyStore=KeyStore.getInstance(“pkcs12”);
FileInputStream identityKeyStoreFile=新的FileInputStream(新文件(“src/Cert.p12”);
加载(identityKeyStore文件,CERT_PASSWORD.tocharray());
KeyStore trustKeyStore=KeyStore.getInstance(“jks”);
FileInputStream trustKeyStoreFile=newfileinputstream(新文件(“src/truststore.jks”);
load(trustKeyStoreFile,CERT_PASSWORD.toCharArray());
SSLContext SSLContext=SSLContexts.custom()
//加载标识密钥库
.loadKeyMaterial(identityKeyStore,CERT_PASSWORD.ToCharray(),new PrivateKeyStrategy()){
@凌驾
公共字符串选择器(映射别名、套接字){
返回证书别名;
}
})
//加载信任密钥库
.loadTrustMaterial(信任密钥库,空)
.build();
SSLConnectionSocketFactory SSLConnectionSocketFactory=新的SSLConnectionSocketFactory(sslContext,
新字符串[]{“TLSv1.2”,“TLSv1.1”},
无效的
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient=HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
//调用SSL端点
被调用点(客户端);
}捕获(例外情况除外){
System.out.println(“轰,我们失败了:+ex”);
例如printStackTrace();
}
}
私有静态无效调用点(CloseableHttpClient aHTTPClient){
试试{
String ServerUrl=“我的公司URL”;
System.out.println(“调用URL:+ServerUrl”);
HttpPost=新的HttpPost(服务器URL);
setHeader(“内容类型”、“应用程序/json”);
System.out.println(“**POST**请求Url:+POST.getURI());
HttpResponse response=aHTTPClient.execute(post);
int responseCode=response.getStatusLine().getStatusCode();
System.out.println(“响应代码:“+responseCode”);
System.out.println(“内容:-\n”);
BufferedReader rd=新的BufferedReader(新的InputStreamReader(response.getEntity().getContent());
弦线;
而((line=rd.readLine())!=null){
系统输出打印项次(行);
}
}捕获(例外情况除外){
System.out.println(“轰,我们失败了:+ex”);
例如printStackTrace();
}
}
示例Curl调用:
curl-v--key.pem--pass******--cert cert.pem MyCompanyURL

我想您知道ssl握手是如何工作的。如果没有,就去了解一下。然后使用wireshark查看ssl握手。您将获得比一些该死的http库解释更好的ssl警报详细信息。如果有什么区别的话,这是一个误导性的错误

有一点是肯定的,您的服务器必须信任您的客户端证书,所以我假设您首先已经正确地设置了内容;你说你试过卷发,但没有说是否有效


最后,我不认识这些SSL类,所以您要导入的不是jdk的jsse类;您可能是这种库的受害者。

我想您知道ssl握手是如何工作的。如果没有,就去了解一下。然后使用wireshark查看ssl握手。您将获得比一些该死的http库解释更好的ssl警报详细信息。如果有什么区别的话,这是一个误导性的错误

有一点是肯定的,您的服务器必须信任您的客户端证书,所以我假设您首先已经正确地设置了内容;你说你试过卷发,但没有说是否有效


最后,我不认识这些SSL类,所以您要导入的不是jdk的jsse类;您可能是此类库的受害者。

当我使用核心jdk jsse类时,程序运行良好。我之所以使用上述程序,是因为我从互联网上复制了其中一个示例。

当我使用核心jdk jsse类时,程序运行良好。我使用上述程序是因为我从互联网上复制了其中一个示例。

查看您在
curl
中使用的确切命令会很有用吗?我想说,在客户端,您需要的是服务器证书,而不是客户端证书。@DmytroChasovskyi我已将我的问题编辑为包含curlcall@VictorCalatramas据我所知,服务器证书进入信任库,客户端证书将在进行双向ssl调用时发送。如果我错了,请纠正我一切都取决于服务器的实现,可以确定的是客户端和服务器需要彼此的证书(.pem)。查看您在
curl
中使用的确切命令将非常有用。我想说,在客户端,您需要的是服务器证书,而不是客户端证书。@DmytroChasovskyi我已将我的问题编辑为包含curlcall@VictorCalatramas据我所知,服务器证书进入信任库,客户端证书将在进行双向ssl调用时发送。如果我错了,请纠正我,一切都取决于服务器的实现,可以确定的是,客户端和服务器彼此需要证书(.pem)Ok。那么,您可以添加导入,告诉我们有关ssl l的信息吗