05.07.2007 14:56:09JTLS и Tomcat Ответов: 7
Даниил Швед, Астра-СТ
Нам не удается заставить работать JTLS с сервером Apache Tomcat. JTLS установлен по "Руководству программиста КриптоПро JTLS". В файле server.xml прописан коннектор:
<Connector port="8443" maxHttpHeaderSize="8192"
SSLEnabled="true"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false"
sslProtocol="GostTLS"
algorithm="GostX509"
keystoreProvider="JCP"
keystoreType="HDImageStore"
keystoreFile="c:\...\truststore"
keystorePass="tomcat"
truststoreType="HDImageStore"
truststoreFile="c:\...\truststore"
truststorePass="tomcat"
keyalg="GOST3410"
sigalg="GOST3411withGOST3410EL"
keyAlias="server" />

Файл c:\...\truststore реально существует, был создан исполнением KeyStore.load(null,null);KeyStore.store(имя, пароль). Пароль одинаковый на truststore и на контейнере с ключом в HDImageStore - tomcat, как и указано в server.xml. Tomcat запускается без сообщений об ошибке, зато с сообщением о старте JCP.

Несмотря на все это, зайти по https не получается. В качестве клиента пытались использовать firefox и ie. Firefox выдает сообщение "Could not establish an encrypted connection because certificate presented by www.dan.shved is invalid or corrupted. Error code: -8102". IE выдает стандартную страницу "Невозможно отобразить страницу". На машине (она и клиент, и сервер) установлен CryptoPro CSP KC1 3.0.3293.

Подскажите, пожалуйста, в чем может быть проблема. Спасибо.
 
Ответы:
06.07.2007 16:44:16Русев Андрей
Для проверки работы пользуйтесь только теми приложениями, которые работают через CryptoAPI, либо JSSE в Java. FireFox и Opera ничего этого не умеют. Подробную информацию о всех этапах соединения выдаёт csptest:
csptest -tlsc -server server_name_or_ip -port port_number -proto 4 -v

Tomcat почти всегда стартует успешно, но это мало что говорит, о том, какие коннекторы будут работать. Используйте "netstat -a", чтобы узнать какие порты он реально слушает.

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

static void installExtention(String alias, String keyPass, String rootCertPath)
throws NoSuchAlgorithmException, IOException,
CertificateException, NoSuchProviderException, KeyStoreException,
UnrecoverableKeyException {
KeyStore hdImageStore;
hdImageStore = KeyStore.getInstance("HDImageStore", "JCP");
hdImageStore.load(null, null);
PrivateKey key = (PrivateKey)hdImageStore.getKey(alias, keyPass != null ? keyPass.toCharArray() : null);
Certificate cert = hdImageStore.getCertificate(alias);
CertificateFactory cf = CertificateFactory.getInstance("X509");
Certificate root = cf.generateCertificate(
new FileInputStream(new File(rootCertPath)));
Certificate[] chain = new Certificate[2];
chain[0] = cert;
chain[1] = root;
hdImageStore.setKeyEntry(alias, key, keyPass != null ? keyPass.toCharArray() : null, chain);
}
09.07.2007 9:11:38Даниил Швед, Астра-СТ
1) netstat -na находит, что кто-то на порту 8443 (на этот порт настроен коннектор SSL) LISTENING. Это точно tomcat'овский коннектор, потому что порт слушается, только когда запущен Tomcat.

2) Далее, запись в хранилище ключей мы создавали ровно так, как показано в Вашем коде. Правда потом, во избежание случайных ошибок, сгенерировали самоподписанный сертификат, пользуясь руководством программиста JCP. Сертификат действительный, в дополнительных применениях один пункт - Аутентификация сервера, основные применения - (Цифровая подпись, Неотрекаемость, Шифрование ключа, Key Agreement, Подпись сертификата ключа).

3) Вот что выдает csptest:
C:\Program Files\Crypto Pro\CSP>csptest -tlsc -server 127.0.0.1 -port 8443 -proto 4 -v
CSP (Type:71) v3.0.3293 KC1 Release OS:Windows CPU:IA32 FastCode:READY,ENABLED.
CSP (Type:75) v3.0.3293 KC1 Release OS:Windows CPU:IA32 FastCode:READY,ENABLED.
csptest -tlsc -server 127.0.0.1 -port 8443 -proto 4 -v
76 bytes of handshake data sent
617 bytes of handshake data received
**** Error 0x80090308 returned by InitializeSecurityContext (2)
An error occurred in running the program.
.\WebClient.c:417:Error performing handshake.
Error number 57 (87).
Параметр задан неверно.

Total: SYS: 0.031 sec USR: 0.063 sec UTC: 2.687 sec
[ErrorCode: 0x00000001]

Мне кажется, судя по этому выводу, что ошибка происходит на довольно низком уровне (вроде неверного формата данных в handshake-сообщениях), поэтому без Вашей помощи нам не разобраться. Какие наиболее вероятные причины такой "грубой" ошибки?
09.07.2007 10:23:16Даниил Швед, Астра-СТ
Еще кое-что. Сейчас специально получил новый сертификат на crypropro.ru/certsrv. Создал для него цепочку из 2 сертификатов (пользуясь Вашим java-кодом), при этом .cer-файл с корневым сертификатом получил экспортом этого сертификата из хранилища Windows. Так вот, я задал этот сертификат и для tomcat, и для IIS. csptest iis'а проходит успешно, при этом первая полученная порция handshake - 880 байт. С tomcat'ом - результат прежний (ошибка), но первый полученный кусок handshake - аж 1475 байт. Еще на всякий случай сменил пароль контейнера на неправильный - handshake от tomcat'а сократился до 7 байт, следовательно с правильным паролем tomcat'овый коннектор успешно открывает контейнер.
09.07.2007 13:51:43Русев Андрей
Вы всё делаете правильно. Ошибка у нас. Рекомендации:
1. использовать на клиентской машине Windows 2000, тогда CSP 2.0/3.0 будут работать с JTLS-сервером без ограничений.
2. позволять клиенту дополнительно использовать SSL 2.0 (на деле всё равно будет выбран TLS, но при установлении соедиения сервер TLS его хочет - это суть ошибки). Это можно сделать, указав галку в настройках "Дополнительно" в IE, а csptest запускать без "-proto 4" (не заставлять использовать TLS).
09.07.2007 15:51:39Даниил Швед, Астра-СТ
Спасибо за столь утешительный ответ. Есть еще вопросы
1) Пока попробовали в качестве клиента windows 2000 server, соединиться с tomcat не удалось.
2) Когда убрали -proto 4, прогресс зашел чуть дальше. Было уже 4 сообщения (2 отправки handshake и 2 получения), но потом ошибка 0x80090317 (раньше была другая ошибка).
3) Вы не могли бы перечислить, в каких ОС есть ограничения на соединение с jtls сервером? А у jtls-клиента есть такие ограничения?
4) Возможно, это поможет. Когда я взял сервер (без клиента) из примера jtls в "руководстве по jtls" и соединился с ним csptest -tlsc с windows server 2000, сервер выдал сообщение в духе "у нас с клиентом нет общих cipher suit'ов".
Спасибо.
09.07.2007 17:27:29Русев Андрей
1. Похоже, я неточно описал про W2k: на нём надо запрещать SSL 2.0, а на XP/2003 наоборот. На Vista/Windows Mobile (CSP 3.6) у меня работает в любом случае. Это очень поверхностные наблюдения за сегодняшнее утро и указывают лишь направление возможного решения. Проблема, как вы верно заметили, в несогласованности наборов шифр-сьют - здесь надо просто исправлять ошибку.
2. Это ошибка SEC_E_CONTEXT_EXPIRED - её получает участник после того, как второй закрывает соединение. Причины закрытия надо выяснять...
3. На Windows - как описано выше. *nix-подобные системы работают всегда. JTLS-клиент должен работать в любом случае.
4. Спасибо.
07.10.2007 1:58:20Андрей
Подскажите, пожалуйста, в каком состоянии находится решение этой проблемы. У меня клиент и сервер (tomcat) находятся под XP.