Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как URLConnection использовать с HTTPS и SSL 
:(
    Опции темы
LSD
Дата 15.4.2006, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Использование защищенного соединения на основе 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.

Желаю успеха!


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0733 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.