当前位置: 首页 > 知识库问答 >
问题:

(Java)没有发送所需的SSL证书(用于curl调用时工作正常)

周翼
2023-03-14

因此,我试图通过在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();
    }

}

Curl调用示例:Curl-v--key key.pem--pass******--cert cert.pem MyCompanyURL

共有1个答案

长孙鸿振
2023-03-14

我想您知道ssl握手是如何工作的吧。如果不是,就去认识一下。然后使用wireshark查看ssl握手。您将获得比某些该死的http库解释更好的ssl警报细节。如果有的话,这是一个误导性的错误。

有一点是肯定的,你的服务器必须信任你的客户机证书,所以我假设你首先正确地设置了这些东西;你说你试过卷曲,但你没说它是否有效。

最后,我无法识别这些SSL类,因此您要导入的是JDK的jsse类以外的东西;你可能会成为这样的图书馆的牺牲品。

 类似资料:
  • 问题内容: 2014年11月29日更新- 这仍然是一个问题,Godaddy似乎不在乎也不会对此做任何事情。几个月前,Godaddy安全产品副总裁在这里发表了一篇博客文章,指出正在修复该问题,并提供了一种临时解决方法,但是到目前为止,没有任何变化。重要的是要注意,Godaddy的G2 CA服务器已经存在至少5年了,在那时,Godaddy尚未采取适当的步骤来解决此已知问题。提供的解决方法仅是一种解决方

  • 我对使用Java的密码学非常陌生。我必须建立一个程序,交换证书之前,任何数据通信发生。我使用sslSockets来构建基本的客户机-服务器程序,而不是使用HTTP/S,这只是为了获得额外的安全性。(想知道Socket和sslsocket之间的区别。这是否意味着所有东西都是自动加密的?) 以下是我更新的服务器代码: PS:我的客户端代码:

  • 问题内容: 是否可以在不使用Java证书的情况下将ssl与httpconnection一起使用?我想使用随机数或密钥。 感谢Raihan 问题答案: 尽管SSL / TLS并非严格要求证书,但HTTPS 要求使用证书,因为RFC 2818 (尤其是第3.1节)明确提到了X.509证书。 您可以在ServerFault的此答案中找到一个非常类似的问题的更多详细信息。 没有证书的任何操作都将超出RFC

  • 问题内容: 我正在使用具有多个唯一标识的从属进程的分布式应用程序,这些进程将通过启用SSL的套接字与主应用程序进行通信。该应用程序用Java编写。 我需要一些帮助来了解SSLSocket,或者更确切地说,是它们使用的证书。 我正在寻找的人可以告诉我我是否正确理解了证书链的基本工作原理,但是我也不会拒绝代码示例。 我想要一个服务器本身具有CA签名证书的设置,每个从属服务器都将获得由主应用程序创建的自

  • 我快被这个问题弄疯了。我在Laravel上有两个站点在https上互相调用(用OAUTH2登录,passport/sociate)。两者都安装在我的本地开发服务器上,在MAMP,MAMP自动签名的证书。 我到处都能找到这个解决方案:把cacert.pem文件放在某个地方,把路径写在php.ini中 完成,Apache重新启动,设置正确地出现在两个站点的phpinfo()中。然而,错误依然存在。有人

  • 我试图用curl调用RESTAPI。apiendpoint在程序中动态生成,并上载json文件。 在这里,我正在打印生成的命令,当我从shell运行该命令时,它正在按预期工作。但是,使用Popen运行相同的命令时会抛出一些json验证错误,这是错误的