Читаем контейнер закрытого ключа КриптоПро средствами OpenSSL
Речь пойдет о файлах primary.key, masks.key и header.key, которые лежат в директории ххххх.000 на флешке. Данные файлы входят в состав криптоконтейнера закрытого ключа электронной подписи криптопровайдера КриптоПро, формат которого нигде не опубликован. Целью данной статьи является чтение контейнера и преобразование закрытого ключа в формат, который может быть прочитан в библиотеке OpenSSL. Долгое время было распространено ошибочное суждение, что достаточно сделать нечто вида (primary_key XOR masks_key) и мы получим закрытый ключ в чистом (raw) виде, однако забегая вперед, можно утверждать, что в КриптоПро было применено более сложное преобразование, в худшем случае состоящее из более чем 2000 (двух тысяч) операций хеширования.
Файл primary.key
Содержит 32 байта ключа в формате Asn1. Это только половина ключа, полный ключ получается при делении этого числа по модулю Q на маску. Поле, хранящее модуль Q в библиотеке OpenSSL имеет название order. Маска лежит в файле masks.key:
Файл masks.key
Содержит 32 байта маски ключа в формате Asn1, зашифрованного на ключе хранения pwd_key. Далее 12 байт «затравочной» информации для генерации ключа хранения pwd_key, если криптоконтейнер защищен паролем, то пароль также участвует в генерации ключа хранения.
Далее контрольная сумма (имитозащита) 4 байта. Контрольной информацией для простоты мы пользоваться не будем, общий контроль будет осуществляться путем генерации открытого ключа и сравнения первых 8 байт полученного ключа с соответствующим полем из файла header.key:
Файл header.key
Читаем закрытый ключ и конвертируем
Основную работу выполняют следующие 3 функции:
1. Создаем ключ хранения исходя из 12-ти байтовой «соли» и пароля.
2. Расшифровываем основной ключ на ключе хранения.
3. Делим ключ с маской на маску.
Но так как в библиотеке OpenSLL операция деления по модулю традиционно отсутствует, пользуемся операцией взятия обратного числа и умножением.
Сборка утилиты конвертирования ключа
Далее сборка исходников описана для Linux версии.
Версию для Windows можно скачать отсюда там же есть сертификаты и закрытый ключ для тестирования, для сборки потребуется бесплатный компилятор Borland C++ 5.5
Компиляция OpenSSL библиотеки
После скачивания и распаковки исходных текстов openssl в целевой директории выполняем команды:
Получаем готовую библиотеку libcrypto.a в текущей директории.
Также потребуются заголовочные файлы из директорий engines/ccgost и include.
Компиляция privkey.c
Формирование файла закрытого ключа private.key
Тестовый закрытый ключ в криптоконтейнере lp-9a0fe.000, сертификат открытого ключа signer.cer и другие файлы для тестирования можно взять отсюда
Получаем результат работы:
Cохраняем в private.key
Пользуемся закрытым ключом private.key для подписывания файла file.txt
Проверяем подпись
Все работает просто замечательно!
Спасибо за внимание. Это была моя первая статья на хабре.
Согласно официальной документации Python 3, ошибка KeyError возникает, когда ключ набора (словаря) не найден в наборе существующих ключей.
Эта ошибка встречается, когда мы пытаемся получить или удалить значение ключа из словаря, и этот ключ не существует в словаре.
Доступ к ключам словаря:
Однако вышеуказанный способ, то есть использование квадратных скобок, имеет один недостаток. Если ключ не существует, мы получаем KeyError.
Удаление несуществующего ключа:
Чтобы справиться с такими случаями, мы можем использовать один из следующих методов, основанных на сценарии.
— Используйте метод get()
— проверить наличие ключа
Мы можем проверить, существует ли какой-либо конкретный ключ в словаре или нет, и затем на основании этого можно предпринять действия. Например:
— Используйте try-exc
Если вы не используете или не хотите использовать метод get для доступа к ключам в словаре, используйте блок try-exc.
— Получить все ключи и перебрать словарь
— Или вы можете напрямую перебирать словарь для пар ключ и значение, используя метод items().
Аналогично, для удаления значения ключа из словаря мы можем использовать метод pop() вместо del.
Таким образом, чтобы избежать ошибки KeyError в случае удаления ключа, мы должны передать значение по умолчанию, которое будет возвращено, если ключ не найден, в качестве второго параметра для pop()
Шпоры по сертификатам X.509
Чудище обло, озорно, огромно, стозевно и лаяй.
Кстати что общего между LDAP, SNMP и X.509 ну кроме того, что им еще не скоро предстоит собрать стадионы фанатов? Их объединяет ASN.1 — мета-язык описания объектов древности. Если бы эти технологии создавали сейчас, в ход бы пошли XML, DTD или какой-нибудь другой ML. Но в то время стандарты создавались титанами, для которых даже SNMP был простым делом.
Словарный запас
Определение X.509 сертификатов есть в архиве ITU-T
Для того, чтобы досконально понять обозначения и синтаксис, придется читать спеки X.680 редакции 2008 г., где есть полное описание ASN.1. В понятиях ASN.1 SEQUENCE обозначает примерно то же самое, что и struct в Си. Это может сбить с толку, ведь по семантике оно должно было соответствовать скорее массиву. И тем не менее.
Стандарт X.690 определяет следующие правила кодирования структур данных, созданных в соответствии с ASN.1: BER (Basic Encoding Rules), CER (Canonical Encoding Rules), DER (Distinguished Encoding Rules). Есть даже XER (XML Encoding Rules), который на практике мне никогда не встречался.
Да, но для чего нужны сертификаты X.509, которые доставляют столько головной боли? Первая и основная функция сертификатов X.509 — служить хранилищем открытого или публичного ключа PKI (public key infrastructure). К этой функции нареканий нет, а вот со второй не все так однозначно.
Вторая функция сертификатов X.509 заключается в том, чтобы предъявитель сего был принят человеком, либо программой в качестве истинного владельца некоего цифрового актива: доменного имени, веб сайта и пр. Это получается по-разному, далеко не все сертификаты имеют высокую ликвидность, если пользоваться финансовой терминологией. Полгода назад Гугл пригрозил компании Симантек, что перестанет доверять их сертификатам из-за того, что те выпустили аж 30,000 неисправных сертификатов.
Номенклатура сертификатов
Давайте рассмотрим, какие сертификаты X.509 встречаются в природе, если рассматривать их по расположению в пищевой цепочке доверия.
По степени крутизны дороговизны и надежности сертификаты делятся на 3 вида: DV, OV и EV.
Редко, кто на это готов раскошелиться. Навскидку Яндекс, StackOverflow.com и Хабр могут жить и без него. Но те, кто готов пойти ради этого на жертвы должны выполнить следующие требования:
По свои свойствам сертификаты бывают следующих типов.
В России понятие КС квалифицированного сертификата определено законодательно в связи с доступом к ГосУслугам. По ссыске Хабрапост с былиной об извлечении персональных данных из КС.
Откуда берутся сертификаты?
Еще совсем недавно было всего 2 способа заполучить X.509 сертификат, но времена меняются и с недавнего времени есть и третий путь.
Для первого сценария достаточно пары команд и чтобы 2 раза не вставать создадим сертификат с алгоритмом эллиптических кривых. Первым шагом нужно создать закрытый ключ. Считается, что шифрование с алгоритмом эллиптических кривых дает больший выхлоп, если измерять в тактах CPU, либо байтах длины ключа. Поддержка ECC не определена однозначно в TLS Openssl имеет огромное количество опций и команд. Man страница не очень полезна, справочник удобнее использовать так:
Следует серия вопросов, чтобы было чем запомнить поля owner и issuer
Конвертируем связку ключей из проприетарного формата в PKCS12.
Смотрим на результат:
LetsEncrypt
Сценарий №1 — найти следующего в связке
Так и есть, SKI сертификат DigiCert имеет то же значение.
Сценарий №2 — используй subjectAltnName, Люк
Откройте файл openssl.cnf и в секции req добавьте следующие линии.
Далее, в секции [ v3_ca ] укажите.
А дальше все как обычно, создаем закрытый ключ и подписываем сертификат.
Подробная инструкция по OpenVPN v2.3.8 на Windows server 2008R2
Представляю подробную инструкцию по OpenVPN v2.3.8 на Windows server 2008R2 c уровнем шифрования TLS. Так же будут подробно описаны все параметры.
Настройка сервера
Для начала качаем дистрибутив с официально сайта. Запускаем установщик openvpn-install-2.3.8-I001-x86_64. В компонентах включаем следующее:
Указываем путь установки (Все дальнейшие действия будут ориентироваться на данный путь указанный в примере):
В процессе установке потребуется установить виртуальный сетевой адаптер, соглашаемся с установкой.
После успешной установки переходим в каталог “C:\Programm Files\OpenVPN” где создаем директорию “SSL” (каталог может называться как угодно, в последующих настройках будет использоваться именно этот каталог), в данном каталоге будут располагаться сертификаты сервера, алгоритмы шифрования и проверка подлинности клиента.
Переходим в каталог “C:\Programm Files\OpenVPN\easy-rsa”, открываем с помощью notepad или notepad++ (более правильный вариант) «vars.bat» (скрипт, содержащий в себе параметры ответов для создания и генерации клиентских/серверных сертификатов и последующих настроек сервера).
В самом низу файла есть следующие параметры, которые нужно настроить под себя:
set KEY_COUNTRY=RU
set KEY_PROVINCE=MO
set KEY_CITY=MOSCOW
set KEY_ORG=OpenVPN
set KEY_EMAIL=local@mos.local
set KEY_CN=server
set KEY_NAME=server
set KEY_OU=OU
set PKCS11_MODULE_PATH=changeme rem Параметр по умолчанию
set PKCS11_PIN=1234 rem Параметр по умолчанию
В этом же каталоге “C:\Programm Files\OpenVPN\easy-rsa”, есть конфигурационный файл “openssl-1.0.0.cnf”, открываем его с помощью notepad или notepad++ (более правильный вариант) и изменяем настройку, отвечающую за срок жизни сертификатов, по умолчанию 365 дней, продлим срок жизни до 3650 дней.
default_days = 3650 # how long to certify for
Далее будем генерировать следующее:
ca.crt — Собственный доверенный сертификат (Certificate Authority — далее CA) для подписи клиентских сертификатов и для их проверки при авторизации клиента.
dh1024.pem — ключ Диффи Хельмана позволяющий двум и более сторонам получить общий секретный ключ
server.crt — сертификат сервера
server.key — ключ сервера
ta.key — дополнительный ключ для tls-аутентификации (повышение безопасности соединения), сервер и каждый клиент должны иметь копию этого ключа
Открываем командную строку и переходим в каталог “C:\Program Files\OpenVPN\easy-rsa”
cd C:\Program Files\OpenVPN\easy-rsa
Вводим команду “vars” нажимаем Enter (инициируем работу со скриптами, в случае закрытия командной строки, команду “vars” придется вводить заного)
Вводим команду “clean-all” (Очищаем каталог “C:\Program Files\OpenVPN\easy-rsa\keys” c последующим созданием файла“index.txt” (база клиентов, она же database) и “serial” (ключ))
Не закрывая командную строку, проверяем содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должны создаться файлы “index.txt и serial”.
Не закрывая командную строку, проверяем содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должен создаться файл “ta.key”.
Вводим команду “build-dh” — генерация ключа Диффи Хельмана.
Не закрывая командную строку, проверяем содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должен создаться файл “dh1024.pem”.
Вводим команду “build-ca” — генерация ключа центра сертификации (CA)
На все вопросы отвечаем по умолчанию нажатием клавиши Enter, эти параметры мы прописали в “vars.bat”
Не закрывая командную строку, проверяем содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должны создаться файлы “ca.crt и ca.key”.
Вводим команду “build-key-server server” — генерация сертификата сервера.
На вопросы Country Name, State Name, Locality Name и т.д. отвечаем по умолчанию нажатием клавиши Enter до самого конца, эти параметры мы прописали в “vars.bat”, далее будет предложено создание сертификата сроком на 3650 дней (данный параметр мы указывали в openssl-1.0.0.cnf) нажимаем “Y”, будет предложено записать сертификат сервера в базу, нажимаем “Y”.
Не закрывая командную строку, проверяем содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должены создаться файлы “server.crt, server.key, server.csr”.
Вводим команду “build-key revokecrt” — команда для создания пользовательского сертификата, но в данном случае мы создаем произвольный сертификат “revokecrt” для последующей генерации файла “crl.pem”, который отвечает за проверку и последующий отзыв сертификатов. Теоретически данную процедуру можно проделать в самом конце и даже жить без нее, но тогда не сможем отзывать сертификаты и конфигурационный файл “server.ovpn” будет выглядеть иначе.
На вопросы Country Name, State Name, Locality Name и т.д. отвечаем по умолчанию нажатием клавиши Enter до вопросов Common Name и Name, на эти вопросы нужно отвечать согласно названию создаваемого сертификата пользователя, в нашем случае это произвольный сертификат “revokecrt” на оставшиеся вопросы нажимаем Enter, далее будет предложено создание сертификата сроком на 3650 дней (данный параметр мы указывали в openssl-1.0.0.cnf) нажимаем “Y”, будет предложено записать сертификат сервера в базу, нажимаем “Y”.
Не закрывая командную строку, проверяем содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должны создаться файлы “revokecrt.crt, revokecrt.key, revokecrt.csr”
Вводим команду “revoke-full revokecrt” – команда отвечает за отзыв сертификата и последующего создания файла “crl.pem”
Не закрывая командную строку, проверяем содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должен создаться файл “crl.pem”
Теперь создадим сертификат пользователя, аналогично сертификату “revokecrt” см. выше.
Вводим команду “build-key user1” – создаем сертификат пользователя с именем user1
На данном этапе работа с консолью закончена, можно закрыть окно и проверить содержимое каталога “ C:\Program Files\OpenVPN\easy-rsa\keys”, должны создаться файлы “user1.crt, user1.key, user1.csr”
Рекомендую создать папку “Clients” в любом удобном для Вас месте и скопировать туда необходимые файлы для передачи пользователям:
Также хочу обратить Ваше внимание на то, что содержимое папки “keys” удалять нельзя, при создании пользовательских сертификатов или любых изменениях в консоли, делайте копию данного каталога во избежание потерь или случайных генераций сертификатов сервера и обновления базы данных.
Копируем файлы сервера в раннее созданную папку “ssl” в каталоге “ C:\Program Files\OpenVPN\ssl”:
Переходим в каталог “C:\Program Files\OpenVPN\config” и создадим файл конфигурации сервера “server.ovpn” со следующим содержимым:
# Создаем маршрутизируемый IP туннель.
dev tun
# Указываем протокол для подключения.
proto udp
# Указываем порт на котором будем слушать.
port 1194
# Указываем что это TLS сервер.
tls-server
# Указываем путь к доверенному сертификату.
ca «C:\\Program Files\\OpenVPN\\ssl\\ca.crt»
# Указываем путь к сертификату сервера.
cert «C:\\Program Files\\OpenVPN\\ssl\\Server.crt»
# Указываем путь к ключу сервера.
key «C:\\Program Files\\OpenVPN\\ssl\\Server.key»
# Указываем путь к ключю Диффи Хельмана
dh «C:\\Program Files\\OpenVPN\\ssl\\dh1024.pem»
# Указываем адресацию сети.
server 10.8.0.0 255.255.255.0
# Указываем алгоритм шифрования должен быть одинаковый клиент/сервер.
cipher AES-128-CBC
# Указываем не перечитавать файлы ключей при перезапуске туннеля.
persist-key
# Указываем путь к ключу безопасности и устанавливаем параметр сервера 0
tls-auth «C:\\Program Files\\OpenVPN\\ssl\\ta.key» 0
# Разрешаем общаться клиентам внутри тоннеля.
client-to-client
# Указываем каталог с описаниями конфигураций каждого из клиентов.
client-config-dir «C:\\Program Files\\OpenVPN\\ccd»
# Указываем файл с описанием сетей между клиентом и сервером.
ifconfig-pool-persist «C:\\Program Files\\OpenVPN\\ccd\\ipp.txt»
# Указывает сверку по отозванным сертификатам.
crl-verify «C:\\Program Files\\OpenVPN\\easy-rsa\\keys\\crl.pem»
# Указываем путь к логу со статусом.
status «C:\\Program Files\\OpenVPN\\log\\logopenvpn-status.log»
# Указываем путь к логу.
log «C:\\Program Files\\OpenVPN\\log\\openvpn.log»
# Указывает MTU для туннеля, должны быть одинаковые параметры клиент/сервер.
tun-mtu 1500
# Включаем сжатие.
comp-lzo
# Устранение проблем с передачей MTU.
mssfix
# Указывает отсылать ping на удаленный конец тунеля после указанных n-секунд,
# если по туннелю не передавался никакой трафик.
# Указывает, если в течении 120 секунд не было получено ни одного пакета,
# то туннель будет перезапущен.
keepalive 10 120
# Указываем уровень логирования.
verb 3
На сервере где будет крутиться OpenVPN необходимо проделать следующее:
1 – Если вы используете встроенный Брандмауэр Windows, создайте разрешающее правило для входящих и исходящих подключений по протоколу UDP на порт 1194.
2 – В службах сервера найдите OpenVPN Service и установите запуск на автоматический, это позволит автоматически запускаться сервису при перезагрузке сервера.
C рабочего стола сервера запускаем “OpenVPN GUI”, в трее дважды щелкаем по значку “OpenVPN GUI” откроется окно лога, если после запуска сервиса в пункте 2 нечего не произошло, нажимаем слева внизу подключиться и если все хорошо, мы должны увидеть следующее содержимое:
Сервис VPN на сервере запущен и готов принимать клиентов.
Настройка клиента
Запускаем ранее скаченный установщик openvpn-install-2.3.8-I001-x86_64, выбор компонентов оставляем по умолчанию, путь сохраняется прежний.
После успешной установки переходим в каталог “C:\Program Files\OpenVPN\config” и создаем файл конфигурации клиента “test.ovpn” со следующим содержимым:
# Создаем маршрутизируемый IP туннель.
dev tun
# Указываем протокол для подключения.
proto udp
# Указываем IP аддрес сервера с портом.
remote X.X.X.X 1194
# Указываем задержку в секундах для построения маршрута.
route-delay 3
# Указываем чтобы клиент забирал информацию о маршрутизации с сервера.
client
# Указываем что мы являемся TLS клиентом.
tls-client
# Параметр защиты от MitM атак.
ns-cert-type server
# Указываем путь к доверенному сертификату.
ca «C:\\Program Files\\OpenVPN\\ssl\\ca.crt»
# Указываем путь к клиентскому сертификату.
cert «C:\\Program Files\\OpenVPN\\ssl\\user1.crt»
# Указываем путь к клиентскому ключу.
key «C:\\Program Files\\OpenVPN\\ssl\\user1.key»
# Указываем путь к ключу безопасности и устанавливаем параметр клиента 1
tls-auth «C:\\Program Files\\OpenVPN\\ssl\\ta.key» 1
# Указываем алгоритм шифрования должен быть одинаковый клиент/сервер.
cipher AES-128-CBC
# Включаем сжатие.
comp-lzo
# Устранение проблем с передачей MTU.
mssfix
# Указывает MTU для туннеля, должны быть одинаковые параметры клиент/сервер.
tun-mtu 1500
# Указываем, сли в течении 60 секунд не было получено ни одного пакета,
# то туннель будет перезапущен.
ping-restart 60
# Указывает отсылать ping на удаленный конец тунеля после указанных n-секунд,
# если по туннелю не передавался никакой трафик.
ping 10
# Указываем уровень логирования.
verb 3
C рабочего стола запускаем “OpenVPN GUI”, в трее дважды щелкаем по значку “OpenVPN”, откроется окно лога, нажимаем подключиться и если все хорошо, то мы увидим следующее:
Запускаем пинг на 10.8.0.1 и видим что сеть доступна (10.8.0.1 адрес, который получил виртуальный сетевой адаптер на сервере).
На сервере мы увидим лог подключения:
Собственно на этом этапе можно закончить и все в дальнейшем будет работать. Но я хотел бы еще кое-что добавить. Для уменьшения количества файлов у клиента и добавление еще одного пункта в безопасности (пароль на подключение), можно сделать следующее, на этапе создания сертификата пользователя на сервере, выполняем команду “build-key-pkcs12 user2” вместо “build-key user1”, выполняем все аналогично первой команде, до пункта Export Password, в этом пункте необходимо указать пароль, например 12345, данный пароль по факту назначается на сертификат “user2.p12”, при попытке подключения через “OpenVPN”, программа обращается к сертификату и требует пароль (зная пароль, его можно изменить, удалить и т.д).
В таком случае, комплект для пользователя будет состоять из:
Конфигурационный файл “test.ovpn” должны быть следующего содержания:
# Создаем маршрутизируемый IP туннель.
dev tun
# Указываем протокол для подключения.
proto udp
# Указываем IP аддрес сервера с портом.
remote X.X.X.X 1194
# Указываем задержку в секундах для построения маршрута.
route-delay 3
# Указываем чтобы клиент забирал информацию о маршрутизации с сервера.
client
# Указываем что мы являемся TLS клиентом.
tls-client
# Параметр защиты от MitM атак.
ns-cert-type server
# Указываем путь к сертификату.
pkcs12 «C:\\Program Files\\OpenVPN\\ssl\\user2.p12»
# Указываем путь к ключу безопасности и устанавливаем параметр клиента 1
tls-auth «C:\\Program Files\\OpenVPN\\ssl\\ta.key» 1
# Указываем алгоритм шифрования должен быть одинаковый клиент/сервер.
cipher AES-128-CBC
# Включаем сжатие.
comp-lzo
# Устранение проблем с передачей MTU.
mssfix
# Указывает MTU для туннеля, должны быть одинаковые параметры клиент/сервер.
tun-mtu 1500
# Указываем, сли в течении 60 секунд не было получено ни одного пакета,
# то туннель будет перезапущен.
ping-restart 60
# Указывает отсылать ping на удаленный конец тунеля после указанных n-секунд,
# если по туннелю не передавался никакой трафик.
ping 10
# Указываем уровень логирования.
verb 3
Пробуем подключиться, вводим пароль 12345
Если все хорошо видим следующее:
Ну и на последок, как отозвать сертификат пользователя и вообще посмотреть список выданных сертификатов. Сам список храниться по следующему пути “C:\Program Files\OpenVPN\easy-rsa\keys\index.txt”
Для того чтобы отозвать сертификат, заходим в командную строку. Переходим в каталог “C:\Programm Files\OpenVPN\easy-rsa”:
cd C:\Program Files\OpenVPN\easy-rsa
Вводим команду “vars” нажимаем Enter (инициируем работу со скриптами). Вводим команду для отзыва сертификата пользователя “revoke-full user2” (указываем название заведенного раннее пользователя).
После заходим в “index.txt” “C:\Program Files\OpenVPN\easy-rsa\keys\index.txt” и видим, что сертификат отозван “R”.
Не готов сказать на 100%, но судя по описанию, файл “index.txt” проверяется каждый час, соответственно через час, сертификат будет заблокирован, ну или просто достаточно перезапустить сервис на сервере.
Еще рекомендую использовать отдельную учетную запись для службы “OpenVPN Service” и в случае если пользователи будут работать с этим сервером, где развернут VPN, обязательно уберите права у простых пользователей на каталог “C:\Program Files\OpenVPN”.
Всем спасибо, надеюсь, данная статься поможет многим, кто сталкивается с вопросами и не находил подходящих ответов, разжевал как мог.




