Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:


Как URLConnection использовать с HTTPS и SSL

Поиск:
Использование защищенного соединения на основе SSL сокетов.


Протокол SSL предназначен для организации защищенного сетевого соединения. Протокол SSL может быть использован как промежуточный протокол между HTTP и TCP/IP, поэтому его применение HTTP клиентами будет "прозрачно". Чтобы установить связь по протоколу SSL средствами JAVA требуется создать SSL сокеты, которые в последствии используются как обыкновенные сокеты.

Для этого требуется выполнить след. шаги.

1) Создание защищенных сертификатов для клиента и сервера.
2) Создание сервера (имеет серверный SSL сокет).
3) Создание клиента (имеет клиентский SSL сокет).

Создание защищенных сертификатов для клиента и сервера.

Создание защищенных сертификатов можно произвести с помощью утилиты KeyTool входящей в состав JDK. Нам потребуется создать два хранилища ключей: для клиента и для сервера. В каждых из них должны находиться по сертификату: серверному и клиентскому, что бы оде стороны, обменивающиеся информацией могли друг друга опознать.

Создадим хранилище ключей для сервера, сгенерируем ключ, подпишем его, и экспортируем клиенту.
Для клиента выполним аналогичные действия.

/// Создаем ключ для сервера
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -genkey -alias serverKey -keystore ServerKeyStore
Enter keystore password: serverpassword
What is your first and last name?
[Unknown]: myFirstName
What is the name of your organizational unit?
[Unknown]: myOrg
What is the name of your organization?
[Unknown]: myOrg
What is the name of your City or Locality?
[Unknown]: myCity
What is the name of your State or Province?
[Unknown]: myProvince
What is the two-letter country code for this unit?
[Unknown]: myCountryCode
Is CN=myFirstName, OU=myOrg, O=myOrg, L=myCity, ST=myProvince, C=myCountryCode correct?
[no]: y

Enter key password for <serverKey>
(RETURN if same as keystore password): serverkeypassword


/// Создаем ключ для клиента
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -genkey -alias clientKey -keystore ClientKeyStore
Enter keystore password: clientpassword
What is your first and last name?
[Unknown]: ClientName
What is the name of your organizational unit?
[Unknown]: ClientOrgUnit
What is the name of your organization?
[Unknown]: ClientOrg
What is the name of your City or Locality?
[Unknown]: ClientCity
What is the name of your State or Province?
[Unknown]: ClientProvince
What is the two-letter country code for this unit?
[Unknown]: ClientCountryCode
Is CN=ClientName, OU=ClientOrgUnit, O=ClientOrg, L=ClientCity, ST=ClientProvince, C=ClientCountryCod
e correct?
[no]: y

Enter key password for <clientKey>
(RETURN if same as keystore password): clientkeypassword


/// Подписываем ключ клиента.
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -selfcert -alias clientKey -keystore ClientKeyStore
Enter keystore password: clientpassword
Enter key password for <clientKey>clientkeypassword


/// Подписываем ключ сервера.
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -selfcert -alias serverKey -keystore ServerKeyStore
Enter keystore password: serverpassword
Enter key password for <serverKey>serverkeypassword


/// Экспортируем сертификат сервера в хранилище клиента.
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -export -file ServerCert.txt -alias serverKey -keystore ServerKeyStore
Enter keystore password: serverpassword
Certificate stored in file <ServerCert.txt>

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -import -file ServerCert.txt -alias serverKey -keystore ClientKeyStore
Enter keystore password: clientpassword
Owner: CN=myFirstName, OU=myOrg, O=myOrg, L=myCity, ST=myProvince, C=myCountryCode
Issuer: CN=myFirstName, OU=myOrg, O=myOrg, L=myCity, ST=myProvince, C=myCountryCode
Serial number: 443ff9b9
Valid from: Fri Apr 14 23:36:25 MSD 2006 until: Thu Jul 13 23:36:25 MSD 2006
Certificate fingerprints:
MD5: 0D:6D:EC:1A:FD:06:BE:DA:C3:BC:F5:DF:72:29:89:5F
SHA1: 87:4F:4E:F2:DD:55:05:39:84:66:F9:98:7B:D6:C0:64:C0:3E:90:8E
Trust this certificate? [no]: y
Certificate was added to keystore


/// Экспортируем сертификат клиента в хранилище сервера.
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -export -file ClientCert.txt -alias clientKey -keystore ClientKeyStore
Enter keystore password: clientpassword
Certificate stored in file <ClientCert.txt>

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -import -file ClientCert.txt -alias clientKey -keystore ServerKeyStore
Enter keystore password: serverpassword
Owner: CN=ClientName, OU=ClientOrgUnit, O=ClientOrg, L=ClientCity, ST=ClientProvince, C=ClientCountryCode
Issuer: CN=ClientName, OU=ClientOrgUnit, O=ClientOrg, L=ClientCity, ST=ClientProvince, C=ClientCountryCode
Serial number: 443ff966
Valid from: Fri Apr 14 23:35:02 MSD 2006 until: Thu Jul 13 23:35:02 MSD 2006
Certificate fingerprints:
MD5: CB:74:08:EB:EE:D0:B2:C2:AE:F6:73:E3:BE:39:9E:8A
SHA1: CC:A3:86:AE:96:31:61:0C:12:CA:0A:A5:57:8F:7D:A2:EE:FD:37:72
Trust this certificate? [no]: y
Certificate was added to keystore



Далее просмотрим содержимое хранилищ, для уверенности.

/// Для серверного хранилища.
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -list -keystore ServerKeyStore
Enter keystore password: serverpassword

Keystore type: jks
Keystore provider: SUN

Your keystore contains 2 entries

serverkey, 14.04.2006, keyEntry,
Certificate fingerprint (MD5): 0D:6D:EC:1A:FD:06:BE:DA:C3:BC:F5:DF:72:29:89:5F
clientkey, 14.04.2006, trustedCertEntry,
Certificate fingerprint (MD5): CB:74:08:EB:EE:D0:B2:C2:AE:F6:73:E3:BE:39:9E:8A


/// Для клиентского хранилища.
Код

C:\Program Files\Java\jdk1.5.0_06\bin>keytool -list -keystore ClientKeyStore
Enter keystore password: clientpassword

Keystore type: jks
Keystore provider: SUN

Your keystore contains 2 entries

serverkey, 14.04.2006, trustedCertEntry,
Certificate fingerprint (MD5): 0D:6D:EC:1A:FD:06:BE:DA:C3:BC:F5:DF:72:29:89:5F
clientkey, 14.04.2006, keyEntry,
Certificate fingerprint (MD5): CB:74:08:EB:EE:D0:B2:C2:AE:F6:73:E3:BE:39:9E:8A



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


Создание Сервера

Код
package ssltest;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

/**
*
* @author MoonCat
*/
public class SSLServer {

/** Creates a new instance of Main */
public SSLServer() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try {
// Получить экземпляр хранилища ключей.
KeyStore keyStore = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("ServerKeyStore");
keyStore.load(fis, "serverpassword".toCharArray());

// Получить диспетчеры ключей базовой реализации для заданного хранилища ключей.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "serverkeypassword".toCharArray());
KeyManager [] keyManagers = keyManagerFactory.getKeyManagers();

// Получить доверенные диспетчеры базовой реализации.
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
TrustManager [] trustManagers = trustManagerFactory.getTrustManagers();

// Получить защищенное случайное число.
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "SUN");

// Создание SSL контекста
SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(keyManagers, trustManagers, secureRandom);

// Создание фабрики SSL сокетов.
javax.net.ssl.SSLServerSocketFactory sslSocketFactory =
sslContext.getServerSocketFactory();

System.out.println("Creating Server Socket : 1234");

SSLServerSocket sslServerSocket = (SSLServerSocket)
sslSocketFactory.createServerSocket(1234);
sslServerSocket.setNeedClientAuth(true);

// Далее работаем как с обычным сокетом.
System.out.println("Start Listenning Server Socket...");
SSLSocket sslClientSocket = (SSLSocket) sslServerSocket.accept();
System.out.println("Client connetion detected.");
System.out.println("Sending callback message...");
DataOutputStream os = new DataOutputStream(sslClientSocket.getOutputStream());
os.write("Sending simple string to socket".getBytes());

System.out.println("Test connection complite successfully");
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}



Создание Клиента

Код
package ssltest;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

/**
*
* @author MoonCat
*/
public class SSLClient {

/** Creates a new instance of SSLClient */
public SSLClient() {
}
public static void main(String[] args) {
try {
// Получить экземпляр хранилища ключей.
KeyStore keyStore = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("ClientKeyStore");
keyStore.load(fis, "clientpassword".toCharArray());

// Получить диспетчеры ключей базовой реализации для заданного хранилища ключей.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "clientkeypassword".toCharArray());
KeyManager [] keyManagers = keyManagerFactory.getKeyManagers();

// Получить доверенные диспетчеры базовой реализации.
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
TrustManager [] trustManagers = trustManagerFactory.getTrustManagers();

// Получить защищенное случайное число.
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "SUN");

// Создание SSL контекста
SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(keyManagers, trustManagers, secureRandom);

// Создание фабрики SSL сокетов.
javax.net.ssl.SSLSocketFactory sslSocketFactory =
sslContext.getSocketFactory();

// Создаем сокет.
System.out.println("Creating Server Socket : 1234");
SSLSocket sslClientSocket = (SSLSocket) sslSocketFactory.createSocket("localhost", 1234);

BufferedReader br = new BufferedReader(
new InputStreamReader(sslClientSocket.getInputStream()));

while (true) {
String s = br.readLine();
if (s.length() > 0) {
System.out.println( s );
break;
}
}
br.close();
System.out.println("Test connection complite successfully");
} catch (KeyManagementException ex) {
ex.printStackTrace();
} catch (UnrecoverableKeyException ex) {
ex.printStackTrace();
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
} catch (NoSuchProviderException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (KeyStoreException ex) {
ex.printStackTrace();
} catch (CertificateException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}



Код подробно прокомментирован, но суть в следующем: сначала происходит настройка SSLContext необходимыми для аутентификации сертификатами, а потом создаются клиентский и серверный SSL сокеты. После создания с ними можно работать как с простыми сокетами, передавать в них информацию, но она будет шифроваться не заметно для нас. Только если скорость передачи данных несколько упадет.

Запустите сервер а потом клиент. Клиент должен получить ответ от сервера в виде строки: Sending simple string to socket.

Желаю успеха!
Автор: MoonCat






Просмотров: 7257

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную