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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование RMI совместно с SSL 
:(
    Опции темы
LSD
Дата 11.5.2006, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


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

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



 Использование RMI совместно с SSL. 


-------------------------------------------
Предполагается, что читатель знаком с данными темами:
1) Основы технологии RMI (создание простых RMI компонентов и серверов).
Для ознакомления:
http://vingrad.ru/JAVA-JAV-000103
http://vingrad.ru/JAVA-JAV-002305
http://vingrad.ru/JAVA-JAV-002341

2) Основы SSL (что это и зачем это нужно)
3) Создание и использование хранилища ключей ( утилита keytool )
Для ознакомления:
http://vingrad.ru/JAVA-JAV-003023
-------------------------------------------

Не так давно мною была опубликована статья о создании защищенного соединения на основе SSL сокетов.  Теперь я решился дополнить её, и рассказать, как использовать SSL сокеты совместно c RMI. Я не буду рассматривать вопросы создания RMI клиента и сервера, а лишь затрону вопрос об организации безопасного соединения. 

И так, у нас имеется RMI сервер и RMI клиент, которые активно обмениваются информацией. Мы хотим обеспечить секретность данной информации, а так же, аутентификацию участников её обмена. 

Что нам необходимо сделать, чтобы клиент и сервер общались через SSL сокеты:

1) Сгенерировать ключи и сертификаты для клиента и сервера.
2) Создать фабрику защищенных сокетов для RMI клиента.
3) Создать фабрику защищенных сокетов для RMI сервера. 
4) Примененить полученные фабрики в коде клиента и сервера.

Сгенерировать ключи и сертификаты для клиента и сервера. 

О том как создать хранилище ключей, сгенерировать ключи, подписать ключи, а импортировать и экспортировать ключи, подробно описано здесь: http://vingrad.ru/JAVA-JAV-003023

Напомню, что клиент должен обладать собственным (подписанным сертификатом) ключом, которым будет производиться шифрование данных и сертификатом ключа сервера,  что бы иметь возможность аутентифицировать сервер. Напротив, сервер должен обладать собственным (подписанным сертификатом) ключом, которым будет производиться шифрование и сертификатом ключа клиента, что бы  иметь возможность аутентифицировать клиента. 

Хранилище ключей клиента будет содержать:
1) Ключ клиента К1.
2) Сертификат С1 для ключа клиента К1.
3) Сертификат С2 для ключа сервера К2.

Хранилище ключей сервера будет содержать:
1) Ключ сервера К2.
2) Сертификат С2 для ключа сервера К2.
3) Сертификат С1 для ключа клиента К1.


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

Технология RMI позволяет нам самостоятельно определить фабрику, которая будет создавать сокеты для соединения клиента и сервера. Одним из способов является реализация интерфейсов RMIServerSocketFactory и RMIClientSocketFactory, для сервера и клиента соответственно.

 1) Создадим фабрику SSL сокетов для клиента.

Код

class MySslRMIClientSocketFactory implements RMIClientSocketFactory {
   
    public Socket createSocket(String host, int port) throws IOException {
        System.out.println("create client socket......");
        return createClientSocketFactory().createSocket(host, port);
    }
    
    private SSLSocketFactory createClientSocketFactory() {
        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();
            return sslSocketFactory;

        } 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();
        }
        return null;
    }
}


 2) Создадим фабрику SSL сокетов для сервера.

Код

class MySslRMIServerSocketFactory extends SslRMIServerSocketFactory {
    public ServerSocket createServerSocket(int port) throws IOException {
        System.out.println("creating ssl socket......");
        return createServerSocketFactory().createServerSocket(port);
    }
    
    public SSLServerSocketFactory createServerSocketFactory() {
        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();
            
            return sslSocketFactory;
        } catch (KeyManagementException ex) {
            ex.printStackTrace();
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (CertificateException ex) {
            ex.printStackTrace();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (NoSuchProviderException ex) {
            ex.printStackTrace();
        } catch (KeyStoreException ex) {
            ex.printStackTrace();
        } catch (UnrecoverableKeyException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }
}



 3) Применение фабрики для сервера во время создания компонента локального регистра:

Код

public class SimpleRegistrator {
    
    /** Creates a new instance of SimpleRegistrator */
    public SimpleRegistrator() {
    }
    public static void main(String[] args) {
        try {
            int port = 1098;
// Создаем Registry используя нашу SSL фабрику серверных сокетов.
            Registry r = LocateRegistry.createRegistry(port, new SslRMIClientSocketFactory(), new MySslRMIServerSocketFactory());
            r.rebind("rmi://localhost:" + port + "/MyService", new NewInterfaceImpl());
            System.out.println("bind complite.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
            
}


 4) Применение фабрики для клиента: 

Код

public class SimpleClient {
    
    /** Creates a new instance of SimpleClient */
    public SimpleClient() {
    }
    
    public static void main(String[] args) {
        try {
            int port = 1098;
// Получаем Registry используя нашу SSL фабрику клиентских сокетов.
            Registry r = LocateRegistry.getRegistry("localhost", 1098, new MySslRMIClientSocketFactory());
            NewInterface remoteComponent = (NewInterface) r.lookup("rmi://localhost:" + port + "/MyService"); 
        } catch (RemoteException ex) {
            ex.printStackTrace();
        } catch (NotBoundException ex) {
            ex.printStackTrace();
        }
    }
}



--------------------
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.1071 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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