It - archiv

Реалізація тонелювання HTTPS за допомогою JSSE

Створення власного сокета для тонелювання HTTPS під додатки Java Secure Socket Extension.

Бібліотека Java Secure Socket Extension (JSSE), створена команії Sun, дає вам доступ до захищеному Web-сервера з-за меж firewall за допомогою proxy-тоннеллірованія.Прі цьому JSSE чекає відповіді від proxy на запит про проходження, щоб почати з "HTTP 1.0" ; в іншому випадку, вона посилає IOException. Якщо ваш proxy не реагує належним чином, ви повинні реалізувати свій власний тунельний протокол для proxy. У цій статті ви узнаетет, як відкрити SSLSocket, що проходить через proxy, і використовувати його з URLConnection APIs для комунікації з захищеними Web-серверами з-за меж firewall. І так, Java Secure Socket Extension (JSSE) забезпечує доступ до сервера, але щоб це зробити, JSSE-додаток повинен встановити системні свойсва https.ProxyHost і https.ProxyPort. Тунельний код в JSSE здійснює пошук "HTTP 1.0" в отриманому від proxy відповіді. Якщо ваш proxy, як і багато інших, повертає "HTTP 1.1", ви отримаєте IOException. В цьому випадку, вам знадобитися реалізувати свій власний тунельний HTTPS-протокол. Я покажу, як створити захищений сокет, здатний проходити через firewall, і передати його в обробник HTTPS-потоку, щоб відкрити HTTPS URL за допомогою класу URLConnection.

Як відкрити тунельний сокет до proxy

Першим, що потрібно зробити при створенні свого безпечного сокета, буде відкриття тунельного сокета до порту proxy. Код для цієї виснажливої ​​процедури можна знайти в прикладі SSLClientSocketWithTunneling.java. який вкладається в пакет при отриманні JSSE. Спочатку створюється звичайний сокет, соедініняющій вас з портом proxy на хості цього proxy (рядок 65). Потім створюється сам сокет, якій передається методу doTunnelHandshake (). в якому викликається тунельний протокол нашого proxy:

У doTunnelHandshake (). до proxy надсилається http-команда "CONNECT", з ім'ям захищеного сайту і номером порту в якості параметрів (рядок 161). У вихідному тунельному коді в рядку 206 в JSSE код потім перевіряє наявність "HTTP / 1.0 200" в отриманому від proxy відповіді. Якщо proxy вашої компанії містить у відповіді "HTTP 1.1", вивалюється IOException. Щоб обійти це, в нашому випадку код буде шукати у відповіді від proxy "200 Connection Established", що означатиме успішну побудову тунелю (рядок 206). Ви можете модифікувати код, щоб він перевіряв наявність потрібного вам параметра у відповіді від proxy.

Маскування тунельного сокета під SSL-сокет

Після того як ви успішно створили тунельний сокет, ви маскіруетет його під SSL-сокет. Тут теж все гранично просто:

До цього код викликав з SSLSocketFactory метод getDefault (). щоб отримати примірник SSLSocketFactory (рядок 54). Потім він пересилає тунельний сокет, створений на попередньому етапі, в метод createSocket () цього SSLSocketFactory. Метод createSocket () повертає SSLSocket. приєднаний до необхідного нам хосту і порту через тунель proxy. За бажанням можна додати в сокет HandshakeCompletedListener. якщо ви хочете отримувати сигнал про завершення SSL-операції.

І все ж, використання http-команд для SSL-сокета при доступі до Web-сторінок не є ідеальним підходом, оскільки це може означати необхідність завантаження обробника http-протоколу. Замість цього, варто скористатися HTTPS URL APIs, включеними до складу JSSE спеціально для цієї мети. Для цього вам потрібно передати тунельний SSL-сокет в обробник потоку HTTPS URL.

Передача SSL-сокета в обробник потоку HTTPS URL

Бібліотека JSSE містить в пакеті com.sun.net.ssl ​​клас HttpsURLConnection. розширює клас java.net.URLConnection. Об'єкт HttpsURLConnection возврящается методом openConnection () URL-об'єкта, в разі якщо в якості протоколу вказано "HTTPS". Клас HttpsURLConnection містить метод setSSLSocketFactory (). дозволяє встановлювати SSLSocketFactory за вашим вибором. Щоб передати SSL-сокет в обробник потоку HTTPS URL, вам потрібно буде встановити параметри методу setSSLSocketFactory () за допомогою конструктора сокета, що повертає тунельний SSL-сокет, створений вами раніше. Для цього вам потрібно вкласти раніше розглянутий код в клас SSLTunnelSocketFactory. розширює клас SSLSocketFactory. Клас SSLSocketFactory є абстрактним. Для його розширення вам потрібно реалізувати метод createSocket (). щоб повернути тунельний SSL-сокет, створений вами раніше:

Зверніть увагу на те, що SSLTunnelSocketFactory за замовчуванням містить об'єкт SSLSocketFactory. Цей об'єкт SSLSocketFactory може встановлюватися викликом статичного методу getDefault () (рядок 15). Цей об'єкт SSLSocketFactory необхідний вам для накладення на тунельний сокет SSL-сокета, як це говорилося раніше. Ви також викликаєте методи getDefaultCipherSuites () і getSupportedCipherSuites () з вашого об'єкта за замовчуванням в процесі реалізації відповідних абстрактних методів супер-класу SSLSocketFactory. Деталі цієї реалізації можна подивитися в початкових кодах SSLTunnelSocketFactory в Додаткових джерелах.

Тунель через proxy допомогою URLConnection

Прохід через proxy за допомогою URLConnection в вашому JSSE-додатку буде виконаний після того, як ви викличте метод openConnection () і перевірите, чи є повернутий об'єкт об'єктом HttpsURLConnection. Якщо так, ви створюєте екземпляр свого об'єкта SSLTunnelSocketFactory і встановлюєте його в методі setSSLSocketFactory () (рядки 22 - 25):

Тепер ви можете отримувати доступ до HTTPS URL за допомогою API, наданими класом URLConnection. Вам вже не потрібно турбуватися про формат http-команд GET і POST, як у випадку якби ви користувалися SSL Socket API. Повністю вихідний код для SSLTunnelSocketFactory і код програми для з'єднання з захищеним URL за допомогою тунелю proxy можна знайти в Додаткових джерелах. Для компіляції та виконання програми вам доведеться завантажити і інсталювати JSSE з сайту Sun, теж зазначеного в Додаткових джерелах.

висновок

Якщо ваше JSSE-додаток не може пробити собі тунель через firewall вашої організації, вам потрібно реалізувати свій власний тунельний сокет. Зразок коду включений пакет JSSE і показує, як відкривати тунель SSL-сокета. У цій статті ми йдемо трохи далі, щоб показати, як передати тунельний сокет оброблювачу потоку HTTPS URL і допомогти вам уникнути необхідності переписування http-обробника.