【问题标题】:OHttpClient get request with valid I.CA certificateOHttpClient 获取具有有效 I.CA 证书的请求
【发布时间】:2021-02-15 10:12:32
【问题描述】:

我是设置证书的新手,端点需要 I.CA 颁发的有效证书。我有一个带有密码的 .pfx,可以从 Postman 的端点获取数据。但是,我无法从在 localhost:8080 上运行的本地服务器实现相同的目标。

我使用的是 okhttp 4.7.2 版

这是我正在使用的代码的细分,加载不会导致任何错误,仅用于调整演示代码。我在密钥库中有 38 个提供程序,并且只有我加载的 keystoreSpi 下的证书。密钥和证书都不为空,并且似乎包含证书。端点只返回一个 403 (根据文档意味着授权标头('x-api-key'、'Authorization' 或 'x-client-cert')无效。)因为我与 Postman 确认了 api 密钥和令牌是有效的(令牌流正在工作),它可能只是缺少的证书。但我不知道该请求还缺少什么。

        KeyStore keystore = KeyStore.getInstance("PKCS12");
        try (InputStream is = Files.newInputStream(Paths.get("filepath\\cert.pfx"))) {
            keystore.load(is, "password".toCharArray());
        } catch (Exception e) {
            LOG.error(e.getMessage());
        }
        String alias = "myAlias";
        Key key = keystore.getKey(alias, "password".toCharArray());
        Certificate cert = keystore.getCertificate(alias);
        PublicKey publicKey = cert.getPublicKey();

        HeldCertificate heldCertificate = new HeldCertificate.Builder()
                .keyPair(new KeyPair(publicKey, (PrivateKey) key))
                .build();

        HandshakeCertificates handshakeCerts = new HandshakeCertificates.Builder()
                .addPlatformTrustedCertificates()
                .heldCertificate(heldCertificate)
                .build();
        OkHttpClient client = new OkHttpClient().newBuilder().sslSocketFactory(handshakeCerts.sslSocketFactory(), handshakeCerts.trustManager())
                .build();

        Request request = new Request.Builder()
                .url("https://apiendpoint/name")
                .method("GET", null)
                .addHeader("x-api-key", "Bearer apiKey")
                .addHeader("x-correlation-id", "corId")
                .addHeader("Authorization", "Bearer " + accessToken.getAccessToken())
                .build();
        Response response = client.newCall(request).execute();

编辑

我将 response.handshake().peerPrincipal().getName() 作为 CN 我必须集成的端点的名称。但是 response.handshake().localPrincipal().getName() 为空。如何设置 localPrincipal 以包含我加载的证书。

这是成功的邮递员调用。

【问题讨论】:

    标签: java ssl x509certificate okhttp


    【解决方案1】:

    要确认客户端身份验证工作正常,您应该查看握手中的 localPrincipal。

        Call call = client.newCall(new Request.Builder().url(server.url("/")).build());
        Response response = call.execute();
        assertThat(response.handshake().peerPrincipal()).isEqualTo(
            new X500Principal("CN=Local Host"));
        assertThat(response.handshake().localPrincipal()).isEqualTo(
            new X500Principal("CN=Jethro Willis"));
        assertThat(response.body().string()).isEqualTo("abc");
    

    可能是您的客户端证书未被接受,并回退允许连接但请求失败。

    在您的请求中,此标头看起来很麻烦,您确定按原样提供此标头,哪个授权包含实际的访问令牌?

    .addHeader("x-api-key", "Bearer apiKey")
    

    https://swagger.io/docs/specification/authentication/api-keys/

    包括客户端在内的实际握手发生在 OkHttp 下方的层,因此如果它是 JDK 应用程序,那么您可能需要为此启用调试标志。如果您真的有动力,Wireshark 或类似工具也可以帮助您进行调试。

    【讨论】:

    • 我用更多信息更新了这个问题。 localPrincipal 为空,如何使用我的证书正确设置它?
    • > 包括客户端在内的实际握手发生在 OkHttp 下方的一层,因此如果它是 JDK 应用程序,那么您可能需要为此启用调试标志。如果您真的有动力,Wireshark 或类似工具也可以帮助您进行调试。
    猜你喜欢
    • 2010-10-17
    • 1970-01-01
    • 2014-11-24
    • 2021-02-10
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多