#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
Здравствуйте, попробуйте как описано здесь
Комментариев нет:
Отправить комментарий