SSL Error : no suitable certificate found continuing without client authentication in java
I am facing issues with client certificate authentication using java (HttpUrlConnection, HttpClient apache)
I tried through curl it works : curl -v POST -H "Content-Type: application/json" --data Jsondata --cert-type P12 --cert path/to/certificat:password https://url -k
But when i try to execute the some request using java, it gives : no suitable certificate found - continuing without client authentication
code Java using HttpUrlConnection :
KeyStore ks = KeyStore.getInstance("PKCS12"); FileInputStream fis = new FileInputStream(certificatPath); ks.load(fis, password.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, password.toCharArray()); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), null, null); HttpsURLConnection postConnection = (HttpsURLConnection) url.openConnection(); if (postConnection instanceof HttpsURLConnection) { ((HttpsURLConnection)postConnection).setSSLSocketFactory(sslContext.getSocketFactory()); }
in ssl logs the keystore and trustore are loaded correctly
*** found key for : aliasKey *** *** trustStore is: javaHome\jre\lib\security\cacerts trustStore type is : jks trustStore provider is : init truststore
but after "Server done" step, it gives message
Warning: no suitable certificate found - continuing without client authentication *** Certificate chain <Empty>
I tested several solutions but I still have the same error message, even if the keystore is loaded with the same private key CN specified in certificate request
*** CertificateRequest Cert Types: RSA , DSS , ECDSA Supported Signature Algorithms: SHA512withRSA, Unknown (hash:0x6, signature:0x2), SHA512withECDSA, SHA384withRSA, Unknown (hash:0x5, signature:0x2), SHA384withECDSA, SHA256withRSA, SHA256withDSA, SHA256withECDSA, Unknown (hash:0x3, signature:0x1), Unknown (hash:0x3, signature:0x2), Unknown (hash:0x3, signature:0x3), SHA1withRSA, SHA1withDSA, SHA1withECDSA Cert Authorities: CN authorities ....
the some code works perfectly with another certificat in some format p12
when i tested the solution proposed in link How I can tell alias of the wanted key-entry to SSLSocket before connecting? the problem is resolved :
KeyStore ks = KeyStore.getInstance("PKCS12"); FileInputStream fis = new FileInputStream(keystorePath); ks.load(fis, keystorePwd.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, keystorePwd.toCharArray()); final X509KeyManager origKm = (X509KeyManager)kmf.getKeyManagers()[0]; X509KeyManager km = new X509KeyManager() { @Override public String[] getClientAliases(String string, Principal[] prncpls) { return origKm.getClientAliases(string, prncpls);//To change body of generated methods, choose Tools | Templates. } @Override public String chooseClientAlias(String[] strings, Principal[] prncpls, Socket socket) { return certificatAlias; //To change body of generated methods, choose Tools | Templates. } @Override public String[] getServerAliases(String string, Principal[] prncpls) { return origKm.getServerAliases(string, prncpls); //To change body of generated methods, choose Tools | Templates. } @Override public String chooseServerAlias(String string, Principal[] prncpls, Socket socket) { return origKm.chooseServerAlias(string, prncpls, socket);//To change body of generated methods, choose Tools | Templates. } @Override public PrivateKey getPrivateKey(String string) { System.out.println(".getPrivateKey() :"+string) ; return origKm.getPrivateKey(string); } @Override public X509Certificate[] getCertificateChain(String string) { System.out.println(".etCertificateChain :"+string) ; return origKm.getCertificateChain(string); } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(new KeyManager[] { km }, null, null); ``