Страницы

Поиск по вопросам

воскресенье, 12 января 2020 г.

SSL авторизация на сайте по сертификату в связке с логином и паролем

#ssl #java


Подскажите что я делаю не так? 

Необходима авторизация на сайте https://test.local, для авторизации используется
сертификат cert.pfx и связка логин:пароль. 
cert.pfx - я экспортировал из браузера firefox, что бы действительно убедиться что
сертификат верный я его импортировал(в веб браузер) на другие машины. авторизация проходила
успешно.

Из полученного сертифката я создал keystore.jks 

openssl pkcs12 -in custom_cert.p12 -out custom_cert.pem -nodes -nokeys
openssl pkcs12 -in custom_cert.p12 -out custom_key.pem -nodes -nocerts

openssl pkcs8 -topk8 -nocrypt -in custom_key.pem -inform PEM -out custom_key.der
-outform DER
openssl x509 -in custom_cert.pem -inform PEM -out custom_cert.der -outform DER


Вот так вот выглядит мое подключение

String URL = "test.local";

 try {

            KeyStore kS = KeyStore.getInstance( KeyStore.getDefaultType() );
            FileInputStream fIS = new FileInputStream("keystore.jks"); 
            kS.load(fIS, "123456".toCharArray());

            KeyManagerFactory kMF = KeyManagerFactory.getInstance("SunX509");
            kMF.init(kS, "123456".toCharArray());
            KeyManager[] kMs = kMF.getKeyManagers();

            TrustManagerFactory tMF = TrustManagerFactory.getInstance("SunX509");
            tMF.init(kS);
            TrustManager[] tM = tMF.getTrustManagers();


            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(kMs, tM, new SecureRandom());
            SSLContext.setDefault(sslContext);
            javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            SSLSocket sslClientSocket = (SSLSocket) sslSocketFactory.createSocket(URL,443);
            sslClientSocket.startHandshake();


            HttpHost targetHost = new HttpHost(URL, 443, "https");
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);



            CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(
                    new AuthScope(targetHost.getHostName(),443),
                    new UsernamePasswordCredentials("Fedya.Ivakin", "191919"));

            HttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .setDefaultCredentialsProvider(credsProvider)
                    .setSslcontext(sslContext)
                    .build();

            AuthCache authCache = new BasicAuthCache();           
            BasicScheme basicAuth = new BasicScheme();
            authCache.put(targetHost, basicAuth);

            HttpClientContext context = HttpClientContext.create();
            context.setCredentialsProvider(credsProvider);

            HttpGet httpget = new HttpGet("/");

            HttpResponse response = httpclient.execute(targetHost, httpget, context);
            System.out.println(response.getStatusLine());


В результате получаю HTTP/1.1 403 Forbidden.

Хотя ошибок ни каких нет, куда копать? подскажите пожалуйста.
    


Ответы

Ответ 1



Кучу сайтов перерыл. Встречал такие утверждения, что pkcs12 сертификаты java не понимает и надо их конвертировать и кучу еще чего. Но вот так у меня проходит авторизация по сертификату + логин пароль. String URL = "https://test.local:443"; URL url = new URL(URL); HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); con.setSSLSocketFactory(getFactory1(new File("key/User.pfx"), "123456")); Authenticator.setDefault(new MyAuthenticator()); con.setAllowUserInteraction(true); con.setRequestMethod("GET"); con.connect(); domain необходимо указывать именно через два слеша, плюс не нужно указывать зону(ru и тп). Например логин и пароль у нас такой Ivan.Petrov@domain.ru - это логин, 123456 - это пароль class MyAuthenticator extends Authenticator { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("domain\\Ivan.Petrov", "123456".toCharArray()); } } == private SSLSocketFactory getFactory1(File pKeyFile, String pKeyPassword) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException { KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); KeyStore keyStore = KeyStore.getInstance("PKCS12"); InputStream keyInput = new FileInputStream(pKeyFile); keyStore.load(keyInput, pKeyPassword.toCharArray()); keyInput.close(); keyManagerFactory.init(keyStore, pKeyPassword.toCharArray()); TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { //To change body of implemented methods use File | Settings | File Templates. } public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext context = SSLContext.getInstance("TLS"); context.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom()); return context.getSocketFactory(); } Ничего ни пришлось конвертировать и тп. Необходимо экспортировать сертификат пользователя из браузера и закинуть его в приложение.

Ответ 2



Здравствуйте, попробуйте как описано здесь

Комментариев нет:

Отправить комментарий