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


Автор: Fameing 14.4.2006, 10:27
Как получить всю страницу в буфер по HTTPS сейчас изпользую так :

Код

URL urls = new URL(url);
        URLConnection uc = urls.openConnection();
        uc.setDoOutput(false);
        uc.setDoInput(true);
        uc.setUseCaches(false);
        uc.connect();
        BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));



Код

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
    com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA6275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
    com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA6275)
    com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA6275)
    com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA6275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA6275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(DashoA6275)
    sun.net.www.protocol.https.HttpsClient.afterConnect(DashoA6275)
    sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(DashoA6275)
    sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(DashoA6275)
        ......
    javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

Автор: powerOn 14.4.2006, 11:21
Данный код у меня работал:

Код

package urlconnect;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class Main {

    public Main() {
    }

    public static void main(String[] args) {
 
        try {
            URL url = new URL("http://www.vingrad.ru");
            URLConnection uc = url.openConnection();
            uc.connect();
            InputStream is = uc.getInputStream();
            byte b [] = new byte [ 1024 * 1024 * 8];
            is.read(b);
            File f = new File("sss.txt");
            FileOutputStream fos = new FileOutputStream(f);
            fos.write(b);
            fos.close();
            System.out.println("" + b.length);
            
            
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
    
}


Добавлено @ 11:34
Сорри, Fameing, прозевал что по HTTPS надо....

Автор: Fameing 14.4.2006, 11:47
Да а как это можно реализовать с HTTPS?

Плиз помогите. smile smile smile

Автор: Fameing 14.4.2006, 18:01
Уже пробывал добавить сертификат вручную. smile

Код

C:\Documents and Settings\Igor.Yova>keytool -import -trustcacerts -alias serverc
ert -keypass changeit -file c:/java/qqqq.cer -keystore C:\progra~1\Java\j2re1.4.
2_10\lib\security\cacerts


Owner: EMAILADDRESS=TEST ONLY, CN=localhost, OU=TEST ONLY, O=TEST ONLY, L=St. Pe
tersburg, ST=Russia, C=RU
Issuer: [email protected], CN=Service Support Root CA, OU=Su
pport Department, O=Service Ltd., L=St. Petersburg, ST=Russia, C=RU
Serial number: 3
Valid from: Wed Jul 17 15:55:17 EEST 2002 until: Sun Jul 15 15:55:17 EEST 2012
Certificate fingerprints:
         MD5:  8C:35:E3:43:3E:71:5E:4F:F8:EC:E3:D8:79:63:FC:6F
         SHA1: 6C:00:8E:5B:9D:EA:D0:FB:17:C9:CF:75:C7:55:29:5C:26:34:64:A5
Trust this certificate? [no]:  yes
Certificate was added to keystore

Автор: Goliath 14.4.2006, 19:13
http://www.javable.com/javaworld/tips/111_tt/

Автор: powerOn 14.4.2006, 23:15
Использование защищенного соединения на основе 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.

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

(если модераторы не против, то можно оформить как статью для FAQ :-))

Автор: Goliath 14.4.2006, 23:37
Рульное описание smile

Автор: LSD 14.4.2006, 23:47
Цитата(MoonCat @ 15.4.2006, 00:15 Найти цитируемый пост)
(если модераторы не против, то можно оформить как статью для FAQ :-))

Не против smile
Спасибо за статью!

Автор: powerOn 14.4.2006, 23:53
Цитата

Не против smile


Урааа!!! smile

Автор: Fameing 19.4.2006, 17:58
Большое спасиб. 

Автор: Mikkie 20.4.2006, 19:13
Классная статья!
спасибо 

Автор: sergejzr 25.10.2007, 12:00
powerOn, спасибо за отличный туториал!
В свою очередь добавлю генерацию ключей, описанную в туториале powerOn'a на Ant'е, которую написал по долгу службы.
Комменты везде есть. Если коротко- заполняем часть properties по вкусу данными для сервера и клиента и выполняем ant ssl
Код

        <!--
    Generate certificates for HTTPS described in 
    http://forum.vingrad.ru/forum/topic-91873/hl/httpsurlconnectionimpl/index.html 
    by powerOn. Ant routine by sergejzr
    -->
    <target name="ssl">
        <description>
        EN: Generates Server and Client certificates for SSL        
        RU: Здесь будут созданы сертификаты для соеденения SSL между клиентом и сервером.
        </description>

        <!-- 
        EN:
        In English char you have to type in is 'y', in German however 'j'. So type the letter of the JRE locale here-
        RU:
        'yesChar' - буква, которая выбирается в  качестве положительного ответа 
        на вопрос консоли типа 
                         Are you sure? yes|no: 
        К сожалению на разных языках ОС используются разные буквы для этого 
        (Например в Немецком - 'j', в Английском 'y') 
        Я не знаю, как это вытащить из properties, 
        поэтому юзер здесь должен указать её напрямую.
         -->
        <property name="yesChar" value="j" />
        
        <!--
        EN: Directory for temporary storage 
        RU: Директория для сохранения рабочих временных файлов 
        -->
        <property name="tmpCertDir" value="tmp" />

        <!-- 
        EN: 
        Server data , listet as follows:
           1) keystoreServer - File pointer to the server key storage
           2) aliasServer - Keyname (has to be unique within one single storage)
           3) keypassServer - Password for the key
           4) storepassServer - Password for the storage
           5) dnameServer - Your certificate's data        
        RU:
        Данные сервера в следующем порядке:
           1) keystoreServer - Имя файла(хранилище), где будет храниться серверный ключ
           2) aliasServer - Имя ключа (должно быть однозначным в рамках одного хранилища)
           3) keypassServer - Пароль на ключ
           4) storepassServer - Пароль на хранилище
           5) dnameServer - Данные сертификата (можно их тоже переменными сделать)
        -->
        <property name="keystoreServer" value="serverkeystore" />
        <property name="aliasServer" value="serverKey" />
        <property name="keypassServer" value="serverkeypass_pwd" />
        <property name="storepassServer" value="serverstore_pwd" />
        <property name="dnameServer" value="CN=Sergej Z, OU=ServerTrust Group, O=ServerTrust Research Corporation, C=DE" />

        <!-- 
        EN:
        Client data in the same order as described above
        RU:
        Данные клиента в том же проядке, что и данные сервера.
        -->
        <property name="keystoreClient" value="clientkeystore" />
        <property name="aliasClient" value="clientKey" />
        <property name="keypassClient" value="clientkeypass_pwd" />
        <property name="storepassClient" value="klientstore_pwd" />
        <property name="dnameClient" value="CN=Sergej Z, OU=ClientTrust Group, O=ClientTrust Research Corporation, C=DE" />
        <!-- 
        EN:
        Preferences are fine, let ant do the rest!
        RU:
        Настройки окончены, пускай теперь работает муравей! :)
        -->

        <echo message="EN: Remove old certificates"></echo>
        <echo message="RU: Удаляем старые ключи"></echo>
        <delete file="${keystoreServer}">
        </delete>
        <delete file="${keystoreClient}">
        </delete>
            
        <echo message="EN: Create key storage for the client as well as for the server"></echo>
        <echo message="RU: Создаём хранилища ключей для клиента и сервера"></echo>
        <genkey taskname="genkey" alias="${aliasServer}" keypass="${keypassServer}" storepass="${storepassServer}" dname="${dnameServer}" keystore="${keystoreServer}">
        </genkey>
        <genkey taskname="genkey" alias="${aliasClient}" keypass="${keypassClient}" storepass="${storepassClient}" dname="${dnameClient}" keystore="${keystoreClient}">
        </genkey>

        <echo message="EN: Sign client and server certificates"></echo>
        <echo message="RU: Подписываем сертификаты клиента и сервера"></echo>
        <exec dir="" executable="keytool" inputstring="${yesChar}">
            <arg line="-selfcert -alias ${aliasServer} -keystore ${keystoreServer} -keypass ${keypassServer} -storepass ${storepassServer}" />
        </exec>
        <exec dir="" executable="keytool">
            <arg line="-selfcert -alias ${aliasClient} -keystore ${keystoreClient} -keypass ${keypassClient} -storepass ${storepassClient}" />
        </exec>

        <echo message="EN: Export server certificate into client storage"></echo>
        <echo message="RU: Экспортируем серверный сертификат в хранилище клиента"></echo>
        <exec dir="" executable="keytool">
            <arg line="-export -file ${tmpCertDir}/serverCert.txt -alias ${aliasServer} -keystore ${keystoreServer} -keypass ${keypassServer} -storepass ${storepassServer}" />
        </exec>
        <exec dir="" inputstring="j" executable="keytool">
            <arg line="-import -file ${tmpCertDir}/serverCert.txt -alias ${aliasServer} -keystore ${keystoreClient} -keypass ${keypassClient} -storepass ${storepassClient}" />
        </exec>
        
        <echo message="EN: Export client certificate into server storage"></echo>
        <echo message="RU: Экспортируем сертификат клиентс в хранилище сервера"></echo>
        <exec dir="" executable="keytool">
            <arg line="-export -file ${tmpCertDir}/clientCert.txt -alias ${aliasClient} -keystore ${keystoreClient} -keypass ${keypassClient} -storepass ${storepassClient}" />
        </exec>
        <exec dir="" inputstring="j" executable="keytool">
            <arg line="-import -file ${tmpCertDir}/clientCert.txt -alias ${aliasClient} -keystore ${keystoreServer} -keypass ${keypassServer} -storepass ${storepassServer}" />
        </exec>
        
        <echo message="EN: Clean up"></echo>
        <echo message="RU: Уберём за собой"></echo>
        <delete file="${tmpCertDir}/serverCert.txt">
        </delete>
        <delete file="${tmpCertDir}/clientCert.txt">
        </delete>
        
        <echo message="EN: Read check of the client storage"></echo>
        <echo message="RU: Читаем хранилище клиента (просто тест)"></echo>
        <exec dir="" executable="keytool">
            <arg line="-list -keystore ${keystoreClient} -keypass ${keypassClient} -storepass ${storepassClient}" />
        </exec>
        <echo message="EN: Read check of the server storage"></echo>
        <echo message="RU: Читаем хранилище клиента (просто тест)"></echo>
        <exec dir="" executable="keytool">
            <arg line="-list -keystore ${keystoreServer} -keypass ${keypassserver} -storepass ${storepassServer}" />
        </exec>
    </target>

Автор: sergejzr 25.10.2007, 12:24
Чтобы туториал завершить... Не подскажете, как сгенеренные сертификаты использовать через HTTPURLConnection на клиенте и TomCat на сервере. (Думаю, это стандартный вариант коммуникации апплет-сервер).

Автор: ZeusX 10.2.2008, 21:09
sergejzr

Цитата

Чтобы туториал завершить... Не подскажете, как сгенеренные сертификаты использовать через HTTPURLConnection на клиенте и TomCat на сервере. (Думаю, это стандартный вариант коммуникации апплет-сервер).


+1

Автор: Hidrag 10.2.2008, 22:36
Можно просто юзать в приложении org.apache.commons.httpclient тогда никаких заморочек не надо, будет работать одинаково что для http, что для https, проверено мной лично smile
коннектился к https://uslugi.beeline.ru и имея логин и пасс свободно гулял по сайту, считывал нужные мне данные, парсил и выдавал в удобном виде

Автор: pompei 1.7.2009, 11:57
Цитата(sergejzr @ 25.10.2007,  12:24)
Чтобы туториал завершить... Не подскажете, как сгенеренные сертификаты использовать через HTTPURLConnection на клиенте и TomCat на сервере. (Думаю, это стандартный вариант коммуникации апплет-сервер).

Когда используем URLConnection то переход на https с http будет прозрачным, просто меняем урл на урл с https-протоколом, и ВСЁ! (не нужно никаких System.setProperty и прочей ерунды)

Казалось бы просто, но у некоторых это не работает - возникает ошибка....

На самом деле всё работает, просто эта ошибка предусмотрена разработчиками, верней самой концепцией безопасности.

Протокол HTTPS подразумевает, что вы будете работать только с заранее зарегистрированными сертификатами, т.е. с теми сертификаторами, которым вы доверяете.

Ну а так как вы ещё ни чего не говорили по поводу того, кому вы доверяете, а кому нет, то система думает, что вы никому ни чего не доверяете, и все обрубает при работе с HTTPS.

Короче нужно зарегистрировать, те сертификаты к кому вы обращаетесь.

На заметку: когда происходит коннект по протоколу HTTPS, то вначале клиент и сервер обмениваются сертификатами, потом проверяют эти сертификаты, и только потом уже обмениваются данными.

Как получить сертификат у сервера? Как его зарегистрировать? - это хорошие вопросы... я в них сейчас разбираюсь.

Когда разберусь напишу сюда... а ещё лучше если кто-нибудь напишет а я прочитаю...... smile

Автор: pompei 1.7.2009, 13:03

Для того чтобы зарегистрировать новый сертификат для работы с https
протоколом в java необходимо выполнить команду:

keytool -import -alias <алиас сертификата в keystore> \
    -file <файл сертификата> \
    -keystore <файл keystore>

где
    <файл keystore> - файл в котором хранятся сетификаты по алиасам (хранилище сертификатов)
    <алиас сертификата в keystore> - это уникальный идентификатор
        сертификата на уровне хранилища - я ввел абру-кадабру (и всё работало замечательно)

По умолчанию JVM держит своё хранилище сертификатов в файле:
    $JAVA_HOME/jre/lib/security/cacerts

(Его можно поменять с помощью какой-то System.setProperty... но это делать вредно)

Когда я натравил keytool на этот файл, у меня ничего не получилось (он потребовал
пароль, который я не знаю)
Поэтому я стёр этот файл и запустил команду ещё раз (которая указывала на только что стёртый файл)
Он потребовал уже не ввести пароль, а выбрать новый (и подтветдить его)

Дальше я запустил свою программу и всё заработало, так же как и раньше по http, но уже по https!!!!

        * * *
 
Для плучения сертификата можно, например, воспользоваться FireFox-ом:
    Edit -> Preferences -> Advanced 
        -> Encryption -> View Certificates -> Servers -> AddException
            
            Здесь вводим домен с https
            Нажимаем Get Certificate
            Потом View -> Details -> Export...
            сохраняем в файл - это и будет <файл сертификата>



Автор: Anatret 22.7.2010, 14:03
Подскажите плиз. Я не пойму где лежит ClientKeyStore раз его подгружают как фаил.  Если делать как указанно выше в примере,

Код

KeyStore trustStore  = KeyStore.getInstance("JKS");
        FileInputStream fis = new FileInputStream("ClientKeyStore");
        try {
            trustStore.load(fis, "passpass".toCharArray());
        } finally {
            fis.close();
        }

то выдает ошибку 
Код

Exception in thread "main" java.io.FileNotFoundException: ClientKeyStore (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileInputStream.<init>(FileInputStream.java:66)
    at com.logica.banks.ClientCustomSSL.main(ClientCustomSSL.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)

а вот что лежит у меня в ClientKeyStore
Код

vadim@vadim:/billing/www/cbadmin_ora$ keytool -list -keystore ClientKeyStore
Enter keystore password:  passpass

Keystore type: jks
Keystore provider: SUN

Your keystore contains 2 entries

serverkeysydney, 22.07.2010, trustedCertEntry,
Certificate fingerprint (MD5): 00:D0:BE:54:6A:B7:4E:DA:39:6B:A0:14:EC:82:3B:50
clientkey, 22.07.2010, keyEntry,
Certificate fingerprint (MD5): 08:91:CA:01:61:3C:FF:9D:C2:C8:56:E6:F8:E4:9D:38



Автор: Alexandr87 22.7.2010, 14:32
FileInputStream fis = new FileInputStream("/billing/www/cbadmin_ora/ClientKeyStore");

Автор: ReFLeXive 1.12.2010, 13:26
ДОброго времени суток!
У меня проблема в следующем. Есть https сервер, я ему посылаю POST запрос с определенными параметрами, он мне в ответ должен прислать url-encoded строку вида param=value. Так вот, как мне получить эту самую строку от него?
Делаю вот так:

Код

StringBuilder urlString = new StringBuilder( "https://serverurl/" );
urlString.append( "?param1=value1" );
urlString.append( "&param2=value2");
...
URL url = new URL( urlString.toString() );
HttpsURLConnectionImpl con = (HttpsURLConnectionImpl) url.openConnection();
con.setRequestMethod( "POST" );
...


Пытался получить https-заголовки, но там ниче нету; пытался получить через con.getInputStream() - там вроде возвращаются какие то числа, но их что то маловато для ответа... 
Или может я неверно посылаю запрос на сервер? т.е. может сперва нужно установить коннект с сервером (https://serverurl/), затем установить метод POST и уже потом тока отправлять запрос на этот url? каким тогда образом отправить запрос после url.openConnection()?

Автор: Skipy 1.12.2010, 18:36
Вы данные посылаете не POST-ом. 

Вам надо:

1. Получить URLConnection
2. Вызвать setDoOutput(true)
3. Получить output stream
4. Записать туда то, что Вы хотите передать
5. Вызвать connect и getInputStream - только в этот момент запрос пойдет на сервер.

Автор: ReFLeXive 7.12.2010, 15:18
Цитата(Skipy @ 1.12.2010,  18:36)
Вы данные посылаете не POST-ом. 

Вам надо:

1. Получить URLConnection
2. Вызвать setDoOutput(true)
3. Получить output stream
4. Записать туда то, что Вы хотите передать
5. Вызвать connect и getInputStream - только в этот момент запрос пойдет на сервер.

Спасибо за отклик! Сейчас попробую!!!

Автор: ReFLeXive 7.12.2010, 16:00
Видимо я по прежнему не до конца все понимаю и делаю не так.
Вот что я переделал:
Код

URL url = new URL( "https://serverurl/" );
HttpsURLConnectionImpl connection = ( HttpsURLConnectionImpl ) url.openConnection( );
connection.setRequestMethod( "POST" );
connection.setDoOutput( true );
//
StringBuilder urlString = new StringBuilder( );
urlString.append( "?client_orderid=" + clientOrderId );
urlString.append( "&amount=" + amount );
urlString.append( "&currency=" + currency );
urlString.append( "&order_desc=" + description );
//....            
BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( connection.getOutputStream( ) ) );
bw.write( urlString.toString( ).toCharArray( ) );
            
connection.connect( );
//считываем ответ
char[] b = new char[ 1024 * 1024 ];
BufferedReader br = new BufferedReader( new InputStreamReader( connection.getInputStream( ) ) );
br.read( b );


Сервер мне постоянно выдает, что ему не хватает обязательных параметров. Получается, что мои значения из urlString до сервера не доходят. Как правильно посылать параметры запроса к серверу? 
Может быть, нужно делать какой-нибудь URLEncoder.encode()  c каждым параметров в отдельности или для запроса в целом?

Добавлено через 6 минут и 12 секунд
Все кажется разобрался с этим! Я забыл, что надо делать 
Код

bw.close()

для BufferedWriter

Автор: Skipy 8.12.2010, 14:51
А почему у Вас первый параметр с вопросом? Вы же не query string создаете.

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