вторник, 15 сентября 2015 г.

eToken: создать сертификат при помощи openssl

Дано:

1) USB-ключ eToken PRO (JAVA).
2) Операционная система Windows XP с установленным в ней eToken PKI Client-ом.
3) Операционная система Slackware 14.1
4) Центр сертификации Microsoft Active Directory Certificate Services со своим веб-интерфейсом.
5) Некий веб-ресурс, который умеет общаться по https с использованием сертификатов, выданных центром сертификации из п.4.

Требуется:

1) Получить сертификат в центре сертификации
2) Записать полученный сертификат на eToken
3) Подключиться к требуемому веб-ресурсу из-под Windows XP с использованием браузера Internet Explorer.

Решение:

Вообще-то, можно было бы воспользоваться веб-интерфейсом центра сертификации. Но есть маленькая проблема: этот центр с некоторых пор перестал воспринимать Windows XP.

Выглядит это так. Если попытаться при помощи IE8 сделать запрос сертификата через задачу "Advanced certificate request", центр сертификации присылает HTTP-ответ, в котором Content-length указано примеро 90кб, а реальная длина ~30кб, причем невооруженным глазом видно, что ответ оборван посередине какого-то vb-скрипта. Не знаю, с чем это связано, тем более, что если подменять User-agent браузера на другие варианты (например, при помощи чудесной утилиты UAPick), то HTTP-ответы формируются нормально.

Можно было бы при помощи подмены User-agent бы притвориться, скажем, IE9+Win7, но этот вариант не подходит: в современных системах работа с сертификатами на стороне клиента реализуется при помощи CertEnroll API, а в Windows XP для этой цели использовалось XEnroll API. Соответственно, если центр сертификации считает клиента работающим под новой ОС, он отправляет ему скрипты, которые выполняются с ошибками.

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

К счастью, под рукой оказался линукс с его openssl. Схема работы такова:

1. Генерируем 1024-битный ключ (eToken на ключи с большей длиной у меня почему-то ругается):
openssl genrsa -out 0000.key 1024

2. При помощи полученного ключа 0000.key делаем запрос сертификата:
openssl req -new -utf8 -config my.conf -key 0000.key -out 0000.csr
Тут обратим внимание на две опции: -utf8 позволяет заполнять поля запроса русскими буквами, а -config my.conf позволяет в файле my.conf выполнить "тонкую настройку", в частности, у меня этот файл выглядит так:
[req]
default_bits           = 1024
distinguished_name     = req_distinguished_name
req_extensions         = req_ext

[req_distinguished_name]
countryName                    = Country Name (2 letter code)
countryName_default            = RU
countryName_min                = 2
countryName_max                = 2

organizationalUnitName         = Organizational Unit Name (eg, section)

commonName                     = Common Name (eg, YOUR name)
commonName_max                 = 64

[req_ext]
extendedKeyUsage = clientAuth

3. Далее открываем получившийся файл 0000.csr в блокноте и копируем его содержимое в соответствующее поле ввода на веб-странице центра сертификации. Этот центр его переваривает и выдаёт сертификат, скажем, 0000.cer

4. Ключ 0000.key и сертификат 0000.cer сливаем в один файл 0000.p12:
openssl pkcs12 -export -out 0000.p12 -inkey 0000.key -in 0000.cer
и закидываем этот файл на eToken - там в PKI-клиенте есть команда "Импорт сертификата".

Всё. При входе на нужный нам веб-ресурс он штатно должен подхватить сертификат с ключа и применить его по назначению. Если этого не происходит, нужно разбираться, видит ли браузер соответствующий сертификат (Сервис-Свойства обозревателя - вкладка Содержание - кнопка Сертификаты), правильно ли выставлены на компьютере дата-время и т.д., в общем, бр-р-р, тот ещё квест...

Литература:
http://www.websense.com/support/article/kbarticle/How-to-use-OpenSSL-and-Microsoft-Certification-Authority
https://www.openssl.org/docs/manmaster/apps/x509v3_config.html