如何使用 okhttp3 忽略服务器证书?

时间:2021-05-28 14:49:09

标签: java okhttp sslhandshakeexception

我试图忽略带有以下行的服务器证书:

clientCertificatesBuilder.addInsecureHost(HOST); 
.sslSocketFactory(clientCertificates.sslSocketFactory(), 
clientCertificates.trustManager())
.hostnameVerifier((hostname, session) -> true)

如果我尝试提出请求但我不知道该怎么做,我总是会遇到异常。

javax.net.ssl.SSLHandshakeException: PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to find 
valid certification path to requested target

这是我获得 OkHttpClient 的课程:

import okhttp3.OkHttpClient;
import okhttp3.tls.HandshakeCertificates;
import okhttp3.tls.HeldCertificate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;

@Service
public class OkHttpUtils {

@Value("${host}")
private String HOST;

@Value("${public-key-path}")
private String PUBLIC_KEY_PATH;

@Value("${private-key-path}")
private String PRIVATE_KEY_PATH;

@Value("${certificate-path}")
private String CERTIFICATE_PATH;

@Value("${url}")
private String URL;

public OkHttpClient getClient()
        throws NoSuchAlgorithmException, IOException, InvalidKeySpecException, CertificateException {

    String algorithm = "RSA";

    // Read public and private key to create a keypair
    PrivateKey privateKey = KeyUtils.getPemPrivateKey(PRIVATE_KEY_PATH, algorithm);
    PublicKey publicKey = KeyUtils.getPemPublicKey(PUBLIC_KEY_PATH, algorithm);
    KeyPair keyPair = new KeyPair(publicKey, privateKey);

    // Read the certificate
    X509Certificate certificate = KeyUtils.getX509Certificate(CERTIFICATE_PATH);

    // Client certificate, used to authenticate the client
    HeldCertificate clientCertificate = new HeldCertificate(keyPair, certificate);

    // Create handshake certificate (which root certificate/hostname to trust)
    HandshakeCertificates.Builder clientCertificatesBuilder = new HandshakeCertificates.Builder()
            .addPlatformTrustedCertificates() // trust all certificate which are trusted on the platform
            .heldCertificate(clientCertificate); // attach the client certificate

    // Do not verify certificate of the host
    clientCertificatesBuilder.addInsecureHost(HOST);
    HandshakeCertificates clientCertificates = clientCertificatesBuilder.build();

    return new OkHttpClient.Builder()
            .sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
            .hostnameVerifier((hostname, session) -> true) // Do not verify the hostname
            .build();
}
}

在这里我构建请求并得到异常:

    OkHttpClient client = okHttpUtils.getClient();
    HttpUrl.Builder httpBuilder = HttpUrl.parse(url).newBuilder();

    Request request = new Request.Builder()
            .url(httpBuilder.build())
            .addHeader("Authorization", "Handle clientCert=true")
            .addHeader("Accept", "application/json")
            .get()
            .build();
    try (Response response = client.newCall(request).execute()) {
    ...}

感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

我发现了问题: 作为 HOST,我提供的是 IP 地址而不是 URL,目前 OkHttp3 中存在错误,因此无法正常工作。