Ошибка SSL: не найдено подходящего сертификата, продолжающегося без аутентификации клиента в java - PullRequest
0 голосов
/ 11 июля 2020

У меня проблемы с аутентификацией сертификата клиента с использованием java (HttpUrlConnection, HttpClient apache) Я пробовал через curl, он работает: curl -v POST -H "Content-Type: application/json" --data Jsondata --cert-type P12 --cert path/to/certificat:password https://url -k

Но когда я пытаюсь выполнить какой-то запрос, используя java, он дает: no suitable certificate found - continuing without client authentication

код Java с использованием 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());
               } 

в журналах ssl хранилище ключей и трасторе загружены правильно

***
found key for : aliasKey

***
***
trustStore is: javaHome\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is : 
init truststore

, но после шага «Сервер готов» появляется сообщение

Warning: no suitable certificate found - continuing without client authentication

*** Certificate chain
<Empty>

Я тестировал несколько решения, но у меня все еще есть то же сообщение об ошибке, даже если хранилище ключей загружено с тем же закрытым ключом CN, указанным в запросе сертификата

 *** 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 ....

, некоторый код отлично работает с другим сертификатом в некотором формате p12

1 Ответ

0 голосов
/ 14 июля 2020

при тестировании решения, предложенного в ссылке Как я могу определить псевдоним желаемого ключевого входа в SSLSocket перед подключением? проблема решена:

 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);
``
...