Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Нужно пояснить рабочий код (SSL протокол)


Автор: Flashed 5.3.2012, 18:04
Как-то возникла проблема отправки  post запроса https.
Нашел рабочую функцию:
Код

private void setupSSL(){
        SocketFactory blindFactory = null;
        TrustManager[] blindTrustMan = { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] c, String a) {
            }
            public void checkServerTrusted(X509Certificate[] c, String a) {  }
        } };
        try { SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, blindTrustMan, new SecureRandom());
        blindFactory = sc.getSocketFactory();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }

        try
        {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, blindTrustMan, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        }
        catch (Exception localException)
        {
        }
    }

Если её вызывать перед открытием соединения, (перед url.openConnection()), то запрос https отправляется без проблем.
Что делает эта функция? Можете объяснить поэтапно? 

Автор: javafreshglow 18.3.2012, 17:12
Цитата(Flashed @ 5.3.2012,  18:04)
Как-то возникла проблема отправки  post запроса https.
Нашел рабочую функцию:
Код

private void setupSSL(){
        SocketFactory blindFactory = null;
        TrustManager[] blindTrustMan = { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] c, String a) {
            }
            public void checkServerTrusted(X509Certificate[] c, String a) {  }
        } };
        try { SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, blindTrustMan, new SecureRandom());
        blindFactory = sc.getSocketFactory();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }

        try
        {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, blindTrustMan, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        }
        catch (Exception localException)
        {
        }
    }

Если её вызывать перед открытием соединения, (перед url.openConnection()), то запрос https отправляется без проблем.
Что делает эта функция? Можете объяснить поэтапно?

Добрый день.

Создавая подобный менеждер,
Код

new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] c, String a) {
            }
            public void checkServerTrusted(X509Certificate[] c, String a) {  }
        }

Вы доверяете всем сертификатом без проверки.

Далее создаем защищенный context 
Код

SSLContext sc = SSLContext.getInstance("SSL");


Инициализируем, успользуя созданный ранее, менеджер (который всем доверяет). Если не нужно использовать ключи клиента, то можно, как Вы сделали:
Код

sc.init(null, blindTrustMan, new SecureRandom());


Добавим фабрику для создания новых защищенных соединений:
Код

HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());


Для использования ключей, см. ниже.

Также можно создать хранилище ключей клиента:
Код

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());


загрузить ключи (например, из базы)
Код

byte[] key = ... - читаем ключ в массив.
keyStore.load(new ByteArrayInputStream(key), "password".toCharArray());


фабрика для создания менеждера ключей
Код

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");


инициализируем хранилище:
Код

kmf.init(keyStore, "password".toCharArray());


инициализируем ssl контекст, с ключами клиента, для подключения к серверу и менеждером, который доверяет всем серверам:
Код

sc.init(kmf.getKeyManagers(), new TrustManager[]{tm}, null);


tm - Ваш менеджер, который "всем доверяет", созданный в самом начале.

Фабрика для создания защищенных соединений, используя ssl контекст (для сравнения - без ключей см. выше):
Код

org.apache.http.conn.ssl.SSLSocketFactory ssf = new org.apache.http.conn.ssl.SSLSocketFactory(sc);


создаем http клиента:
Код

DefaultHttpClient httpclient = new DefaultHttpClient();


Регистрируем "схему" 
Код

httpclient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, ssf));

схема учитывает особенности протокола.

Далее все просто:
Создаем объект для get запроса
Код

String url = "https://.....";
httpget = new HttpGet(url);


выполним запрос:
Код

HttpResponse response = httpclient.execute(httpget);


проверим ответ:
Код

int statusList = response.getStatusLine();


И получаем заголовок и тело:
Код

HttpEntity entity = response.getEntity();
Header[] has = response.getHeaders(_headerName);


Спрашивайте.

Автор: Flashed 10.5.2012, 13:07
Исчерпывающий ответ. Большое спасибо!  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)