我需要通过发送客户端和密钥证书来调用rest api。我创建了密钥库,如下所示:
openssl pkcs12 -export -in client_cert.pem -inkey client_key.key -out c:\kubectl\jaya\identity.p12
keytool -importkeystore -destkeystore identity.jks -deststorepass Tridium123 -srckeystore identity.p12 -srcstoretype PKCS12 -srcstorepass Tridium123
在下面的代码中,我尝试使用identity.jks和identity.p12进行操作,但是仍然存在相同的问题,客户端证书未发送到服务器。
Curl command and postman works good, but facing issues with Java
curl --request --insecure GET https://dkdk.com/api/v1/namespaces --cert client_cert.pem --key client_key.key
public static void main(String args[])
{
try
{
System.setProperty("javax.net.ssl.trustStore", "C://kubectl//nov12//trust.jks");
System.setProperty("javax.net.ssl.keyStore", "C://kubectl//nov12//identity.p12");
final String allPassword = "Password123";
SSLContext sslContext = SSLContextBuilder.create()
.loadKeyMaterial(new File("C://kubectl//nov12//identity.p12"), allPassword.toCharArray(), allPassword.toCharArray(), (aliases, socket) -> "mykey")
.loadTrustMaterial(new File("C://kubectl//nov12//trust.jks"), allPassword.toCharArray())
.build();
HttpClient client = HttpClients.custom()
.setSSLContext(sslContext)
.build();
HttpGet get = new HttpGet("https://sdsds.com/api/v1/namespaces");
HttpResponse response = client.execute(get);
Arrays.asList(response.getAllHeaders()).stream().forEach(System.out::println);
System.out.println(response.toString());
}
catch(Exception e){
e.printStackTrace();
}
以下是异常:
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
02:16:09.103 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Shutdown connection
02:16:09.104 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection discarded
02:16:09.104 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->https://kaas-edge-admin.arm.com:443][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1640)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at com.example.demo.Sampletest.main(Sampletest.java:74)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
at sun.security.validator.Validator.validate(Validator.java:262)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:237)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1622)
... 21 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
... 27 more
Process finished with exit code 0
我也尝试过以下方法,但还是没有运气:
public static void main(String args[])throws Exception{
PlainJavaHTTPS2Test pt = new PlainJavaHTTPS2Test();
pt.testP12KeyStore();
}
public void testP12KeyStore() throws Exception {
final String KEYSTOREPATH = "c:\\kubectl\\jaya\\identity.p12";
final char[] KEYSTOREPASS = "Tridium123".toCharArray();
final char[] KEYPASS = "Tridium123".toCharArray();
try (InputStream storeStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) {
setSSLFactories(storeStream, "PKCS12", KEYSTOREPASS, KEYPASS);
}
testPlainJavaHTTPS();
}
private static void setSSLFactories(InputStream keyStream, String keystoreType, char[] keyStorePassword, char[] keyPassword) throws Exception
{
KeyStore keyStore = KeyStore.getInstance(keystoreType);
keyStore.load(keyStream, keyStorePassword);
KeyManagerFactory keyFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, keyPassword);
KeyManager[] keyManagers = keyFactory.getKeyManagers();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagers, null, null);
SSLContext.setDefault(sslContext);
}
public void testPlainJavaHTTPS() throws Exception {
String httpsURL = "https://kaas-edge-admin.arm.com/api/v1/namespaces";
URL myUrl = new URL(httpsURL);
HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
conn.setReadTimeout(3000);
conn.setConnectTimeout(8 * 1000);
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String text;
StringBuilder result = new StringBuilder();
while ((text = in.readLine()) != null)
result.append(text);
in.close();
}