我尝试使用Java和Retrofit执行以下curl
命令。
curl -k -d "grant_type=client_cert" -H "Authorization: Basic Base64EncodedValue" -H "Content-Type: application/x-www-form-urlencoded" --cert ./certificate.pem https://taget-domain.com
此时,当使用Java代码(见下文)时,我收到错误:
HTTP FAILED: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
发布完整跟踪here。
代码加载本地密钥库,构建信任管理器工厂,并使用信任管理器工厂设置SSL上下文。然后,Retrofit配置将检索X509信任管理器,并将HTTP客户端设置为使用SSL上下文套接字工厂和X509信任管理器。
有谁知道问题是什么或可能是什么以及相应的解决方案?
以下是两个相关的Java代码片段:
证书配置
public KeyStore keyStore(ConfigurableApplicationContext applicationContext)
throws CertificateException, IOException, NoSuchAlgorithmException, KeyStoreException {
CertificateFactory certificateFactory = CertificateFactory.getInstance(getType());
Certificate certificate;
try (InputStream in = applicationContext.getResource(getCertificateResource())
.getInputStream()) {
certificate = certificateFactory.generateCertificate(in);
}
// Configure key store.
String cacertsPath = System.getProperty("cacerts");
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
Path keyStorePath = Paths.get(cacertsPath);
keyStore.load(Files.newInputStream(keyStorePath), getKeyStorePassword().toCharArray());
keyStore.setCertificateEntry("certificateAlias", certificate);
return keyStore;
}
public TrustManagerFactory trustManagerFactory(@Qualifier("keyStore") KeyStore keyStore)
throws KeyStoreException, NoSuchAlgorithmException {
// Configure trust manager factory.
String trustManagerFactoryAlgo = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(trustManagerFactoryAlgo);
trustManagerFactory.init(keyStore);
return trustManagerFactory;
}
public SSLContext sslContext(
@Qualifier("trustManagerFactory") TrustManagerFactory trustManagerFactory)
throws NoSuchAlgorithmException, KeyManagementException {
X509TrustManager x509TrustManager = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
// Configure SSL context.
SSLContext sslContext = SSLContext.getInstance(getProtocol());
sslContext.init(null, new TrustManager[]{x509TrustManager}, null);
return sslContext;
}
改造配置
public OkHttpClient authOkHttpClient(@Qualifier("sslContext") SSLContext sslContext, @Qualifier("trustManagerFactory")
TrustManagerFactory trustManagerFactory) {
// Configure OkHttp3 logging.
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(Level.BODY);
// Configure HTTP client.
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.addInterceptor(httpLoggingInterceptor);
X509TrustManager x509TrustManager = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
httpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), x509TrustManager);
return httpClientBuilder.build();
}