Обновления Windows от мая 2022 г. могут сломать КриптоПро .NET.
Для Windows Server 2019:
- 2022-05 Накопительное обновление .NET Framework 3.5, 4.7.2 и 4.8 для Windows Server 2019 для x64 систем (KB5013868);
- May 10, 2022-KB5013626 Cumulative Update for .NET Framework 3.5 and 4.8 for Windows 10, version 1809 and Windows Server, version 2019.
Для других ОС номер KB может быть другим, но в названии должно быть что-то про «2022-05» и «.NET Framework».
Как следствие не работает ГОСТ-криптография, в т.ч. могут не работать компоненты DSS (Сервис подписи, Сервис Аналитики и др.).
Одна из ошибок (или Warning) в журнале Приложений:
The certificate key algorithm is not supported.
Необходимо обновить КриптоПро .NET до последней сборки:
КриптоПро .NET 1.0.8174.2 от 19.05.2022
СКЗИ КриптоПро CSP имеет бесплатную 90-дневную лицензию, во время действия которой СКЗИ работает в полнофункциональном режиме. После истечения лицензии требуется обязательное приобретение лицензии и регистрация продукта.
Приобрести лицензию можно одним из следующих способов:
1. Заполнив заявку на нашем официальном сайте.
2. Обратившись в клиентский отдел АО «КАЛУГА АСТРАЛ», позвонив по одному из следующих номеров:
- 8-800-700-86-68 (доб. 12) или (4842) 788-999 (доб. 12) (основной офис в Калуге)
- (812) 702-11-93 (представительство в Санкт-Петербурге)
- (3812) 39-09-93, 43-81-71 (отделение в Омске)
- (383) 319-11-01 (отделение в Новосибирске)
- (347) 214-51-20 (Отделение в Уфе)
3. На официальном сайте ООО “КРИПТО-ПРО”.
Если вы уже приобрели лицензию на право использования СКЗИ КриптоПро CSP, перейдите к этапу ввода лицензии.
Приглашаем всех 6 сентября 2022 года в 11:00 (МСК) принять участие в вебинаре “Особенности реализации требований приказа ФАПСИ №152 по учёту СКЗИ”, который совместно проведут компании КриптоПро и Spacebit.
В ходе мероприятия эксперты рассмотрят вопросы нормативного регулирования учета СКЗИ и выполнения соответствующих требований. Отдельное внимание будет уделено возможностям СКЗИ и особенностям их практического применения.
Ключевые темы:
- Разбор основных требований приказа ФАПСИ №152 по учету СКЗИ;
- Демонстрация возможностей системы X-Control по реализации требований приказа ФАПСИ №152;
- Обзор возможностей СКЗИ КриптоПро CSP 5.0;
- Текущий статус по сертификации различных версий КриптоПро CSP и КриптоПро УЦ.
Участие в мероприятии бесплатное, необходима регистрация.
Наименование | Цена | Количество |
---|---|---|
Лицензия на право использования ПО “КриптоПро .NET” на одном рабочем месте | 900,00 ₽ | |
Лицензия на право использования ПО “КриптоПро .NET” на одном сервере | 15 000,00 ₽ | |
Сертификат на годовую техническую поддержку ПО “КриптоПро .NET” на одном рабочем месте | 600,00 ₽ | |
Сертификат на годовую техническую поддержку ПО “КриптоПро .NET” на одном сервере | 4 150,00 ₽ | |
Сертификат на годовую техническую поддержку ПО “КриптоПро .NET” в одной корпоративной системе | 165 000,00 ₽ | |
Дистрибутив ПО “КриптоПро SDK” на CD * (включает дистрибутивы КриптоПро TSP SDK, КриптоПро OCSP SDK, КриптоПро ЭЦП SDK (CAdES), КриптоПро ЭЦП Browser Plug-in, КриптоПро .NET SDK) | 1 000,00 ₽ | |
Сертификат на годовую техническую поддержку “КриптоПро SDK” * включает в себя консультации разработчиков КриптоПро CSP, КриптоПро JCP, КриптоПро TSP SDK, КриптоПро OCSP SDK, КриптоПро ЭЦП SDK (CAdES), КриптоПро ЭЦП Browser Plug-in, КриптоПро .NET SDK | 82 500,00 ₽ |
- Важное вступление
- Минуточку внимания
- Сертификат со встроенной лицензией
- Сертификат без встроенной лицензии
- Где купить КриптоПро
- Общие сведения
- Сценарии использования
- Документация
- Лицензирование
- Системные требования
- Сертификаты
- Что может послужить причиной такой ошибки
- Решение ошибки: отсутствие электронного сертификата в контейнере закрытого ключа
- Особенности версий КриптоПро
- Приобретение лицензии через сайт КриптоПро
- Немного покодим
- Пробный запуск
- Проверка в КриптоАРМ
- Проверка на Госуслугах
- Проверка в Контур. Крипто
- Что имеем на входе?
- Сборка утилиты конвертирования ключа
- Компиляция OpenSSL библиотеки
- Компиляция privkey
- Формирование файла закрытого ключа private. key
- Пользуемся закрытым ключом private. key для подписывания файла file. txt
- Проверяем подпись
- Done.
- Соберем проект с поддержкой ГОСТ Р 34. 11-2012 256 bit
- Первым делом создадим новую папку
- I – Сборка проекта без сборки corefx для Windows
- II – Сборка проекта со сборкой corefx для Windows
- Читаем закрытый ключ и конвертируем
- Файл header. key
- Файл masks. key
- Ввод лицензии
- Ссылки на публичные источники
- Так, а что надо на выходе?
Важное вступление
В гайде описывается формирование отсоединенной подписи в формате PKCS7 (рядом с файлом появится файл в формате .sig). Такую подпись может запросить нотариус, ЦБ и любой кому нужно долгосрочное хранения подписанного документа. Удобство такой подписи в том, что при улучшении ее до УКЭП CAdES-X Long Type 1 (CMS Advanced Electronic Signatures [1]) в нее добавляется штамп времени, который генерирует TSA (Time-Stamp Protocol [2]) и статус сертификата на момент подписания (OCSP [3]) – подлинность такой подписи можно подтвердить по прошествии длительного периода (Усовершенствованная квалифицированная подпись [4]).
Код основан на репозиториях corefx и DotnetCoreSampleProject – в последнем проще протестировать свои изменения перед переносом в основной проект и он будет отправной точкой по сборке corefx. Судя по записям с форума компании [5], решение для .NET Core в стадии бета-тестирования. Далее по тексту я также буду ссылаться на этот форум. Разработка велась в Visual Studio Community 2019.
Для получения штампа времени использован TSP-сервис http://qs.cryptopro.ru/tsp/tsp.srf
Речь пойдет о файлах primary.key, masks.key и header.key, которые лежат в директории ххххх.000 на флешке. Данные файлы входят в состав криптоконтейнера закрытого ключа электронной подписи криптопровайдера КриптоПро, формат которого нигде не опубликован. Целью данной статьи является чтение контейнера и преобразование закрытого ключа в формат, который может быть прочитан в библиотеке OpenSSL. Долгое время было распространено ошибочное суждение, что достаточно сделать нечто вида (primary_key XOR masks_key) и мы получим закрытый ключ в чистом (raw) виде, однако забегая вперед, можно утверждать, что в КриптоПро было применено более сложное преобразование, в худшем случае состоящее из более чем 2000 (двух тысяч) операций хеширования.
Стоит упомянуть о существовании утилиты P12FromGostCSP которая позволяет конвертировать ключ в формат P12, доступный для работы с OpenSSL, но утилита имеет следующие существенные недостатки:
- Читает контейнер не напрямую, а через криптопровайдер, поэтому там, где кроме OpenSSL ничего нет, не работает.
- Если в свойствах ключа не отмечено, что ключ «экспортируемый», то конвертировать его невозможно.
- В демо версии не формирует файл с ключом, эта возможность присутствует только в платной версии.
kromeda Оставлено | |
Добрый день, Upd: насколько я понял для Windows Server автоматически устанавливается версия CSP серверная и ожидает соответствующую лицензию. Отредактировано пользователем 21 декабря 2021 г. 16:01:02(UTC) | |
Александр Лавник Оставлено | |
Автор: kromeda Добрый день, Upd: насколько я понял для Windows Server автоматически устанавливается версия CSP серверная и ожидает соответствующую лицензию. Здравствуйте. Да, на Windows Server можно активировать только серверную лицензию КриптоПро CSP. | |
1 пользователь поблагодарил Александр Лавник за этот пост. | |
Автор
Ответов
Обновления
КриптоПро CSP (CryptoPRO) ( 1 2 3 4 5 … 109 110 111 112 113 )
» Линейка криптографических утилит (вспомогательных программ)
trasser
14-09-2022 14:32
oppendal
КриптоАРМ (trusted.ru) ( 1 2 3 4 5 6 7 8 9 ) » работа с криптографическими средствами
AAPolyakov
06-08-2022 15:45
TNR
Крипто Про и windows server 2012r2 » Крипто Про и windows server 2012r2 сброс триала или переуст.
Georgettos
24-03-2022 11:53
Dobermannn
“КриптоПро CSP” версии 5.0 для одного TLS-сервера
lovky
22-02-2022 11:47
lopinakolada
КриптоПро PDF 2
PaulAlex
16-02-2021 11:12
lexx_76
КриптоПро .NET » КриптоПро .NET
remul1980
16-01-2020 19:41
MirCyber
нужна СКЗИ КриптоПро СSP » нужна СКЗИ КриптоПро СSP
gruzin18
17-10-2019 12:17
Kent12345
Нужен серверный криптоарм
voldaster
12-12-2018 17:01
klaus65
КриптоАРМ » Ищется ключ
KUSA
12-09-2018 20:56
KUSA
варез КриптоПро Java CSP » пока нужно для обучения, но не факт, что контора потом купит
oneironaut
Скриптовый варез (php, cgi, asp, perl etc) ( 1 2 3 4 5 … 67 68 69 70 71 )
» Часть 3 – ТОЛЬКО поиск, обсуждение в “Web-программирова
Sky hawk
01-04-2018 20:03
ignika
КриптоПро JCP » Нужен ключ КриптоПро JCP. Помогите пожалуйста
supercombo
25-07-2017 09:08
kusahot2
Сигнал-КОМ Крипто-КОМ » (СКЗИ) «Крипто-КОМ 3.2» разработки ЗАО «Сигнал-КОМ»
apasov
23-03-2017 01:57
awinner
КриптоПро под Андроид » разыскивается дистрибутив
financist
10-01-2015 10:53
financist
Скриптовый редактор
iolon
03-05-2014 19:41
nv59
Сборник – 35 самых популярных скриптов » таких как казино, почтовик, пирамида, ивестиционный проект,
AsderKDW
17-02-2012 16:22
www2828ru
Поиск скриптов биржи труда » Поиск скриптов биржи труда
Dgikar
Евфрат, криптосистема ЭЦП » в реестре отсутствует требуемая запись о парам.криптосистемы
Evgen3
Люди, помогите дескрипторы посчитать. » Guardant Steach 2
Salgir
14-11-2007 22:25
Nep
КриптоПро CSP » У кого есть эта программа криптозащиты?
Vladimir54
05-12-2006 20:42
Spectare
СКЗИ КриптоПро CSP и КриптоПро TLS
» http://www.cryptopro.ru/
Metallic
27-05-2006 06:04
DGut
Скриптовый варез (php, cgi, asp, perl etc) ( 1 2 3 4 5 … 96 97 98 99 100 )
» часть 2
Nep
15-05-2006 21:30
Nep
Криптография hta » КАК РАЗШИФРОВАТЬ ЗАШИФРОВАНЫЕ .hta ФАЙЛЫ
liight
Скриптовый варез (php, cgi, asp, perl etc) ( 1 2 3 4 5 … 96 97 98 99 100 )
» требуется
batva
24-08-2004 22:46
Nep
КРИПТОН-ЩИТ » Ищу свежую ломалку
Oleg2004
Общая инструция по установке и настройке доступна по ссылке.
1) В КриптоПро CSP 5.0 (5.0.11455) и в КриптоПро CSP 4.0 активировать лицензию (постоянную/временную для версии 5.0/4.0) можно только через Терминал (Finder-Программы-Утилиты-Терминал) с помощью команды вида:
sudo /opt/cprocsp/sbin/cpconfig -license -set 50501-23456-78901-23456-78901
где вместо 50501-23456-78901-23456-78901 необходимо указать серийный номер приобретенной лицензии КриптоПро CSP.
При появлении строки Password: необходимо ввести пароль пользователя macOS (символы вводимого пароля не отображаются) и нажать Enter.
Проверить статус лицензии можно командой:
/opt/cprocsp/sbin/cpconfig -license -view
2) В КриптоПро CSP 5.0 R2 (5.0.12000) и новее активировать лицензию (постоянную/временную для версии 5.0 или временную для версии 4.0) можно также через панель Инструменты КриптоПро:
Finder
Программы
Инструменты КриптоПро
Общее
Ввести лицензию для меня
Если ещё действует демо-лицензия, то в панели Инструменты КриптоПро продолжит отображаться демо-лицензия до окончания срока её действия.
В этом случае чтобы в панели отображалась новая лицензия её нужно активировать через Терминал как описано в п. (1).
3) Для активации лицензий КриптоПро TSP Client 2.0 и КриптоПро OCSP Client 2.0 соответственно необходимо использовать в Терминале команды вида:
sudo /Applications/CryptoPro_ECP.app/Contents/MacOS/bin/tsputil license -s TA201-23456-78901-23456-78901
sudo /Applications/CryptoPro_ECP.app/Contents/MacOS/bin/ocsputil license -s 0A201-23456-78901-23456-78901
где вместо
TA201-23456-78901-23456-78901 необходимо указать серийный номер приобретенной лицензии КриптоПро TSP Client 2.0.
OA201-23456-78901-23456-78901 необходимо указать серийный номер приобретенной лицензии КриптоПро OCSP Client 2.0.
При появлении строки Password: необходимо ввести пароль пользователя macOS (символы вводимого пароля не отображаются) и нажать Enter.
Проверить статус лицензий можно командами:
/Applications/CryptoPro_ECP.app/Contents/MacOS/bin/tsputil license
/Applications/CryptoPro_ECP.app/Contents/MacOS/bin/ocsputil license
Изучаю вопрос работы с ЭЦП, которую теперь можно получить “бесплатно” (принесите только сертифицированный носитель). Однако, из документации получается, что для работы в ЛК ИП в налоговой нужно установить плагин в браузер, который в свою очередь хочет иметь Crypto Pro, которая платная.
Я всё правильно понял?
То есть для работы с бесплатной КЭП ЭЦП от налоговой нужно купить и Носитель, и лицензию КриптоПро?
—-
UPD: Что я выяснил в процессе
- ЭЦП налоговой не работает с VipNet CSP! Просит именно CryptoPro CSP
- CryptoPro CPS имеет 90 дней пробный период. Бессрочная лицензия в октябре 2021 стоит 2700р.
- Вопрос задан
более года назад
- 14064 просмотра
Крипто-про – криптопровайдер.
Для работы эцп обязателен криптопровайдер, но не обязательна Крипто-про. Есть бесплатные криптопровайдеры, но с ними тяжело, криво и сложно работать. Используйте либо триалку Крипто-про, она даётся на полгода. Либо купите бессрочную версию. Она стоит пару тысяч и закрывает вопрос с криптопровайдером навсегда.
P. S. До этого года эцп выдавали только коммерческие уц и просили за это ещё 5 т.р. сверх стоимости носителя и криптопровайдера, продлевать нужно было ежегодно. И никто не гудел. А сейчас вы покупаете за 2 т.р. Крипто-про, за 500 р носитель и можете на него записывать эцп, полученную в налоговой хоть сто лет.
P. P. S. Если надумаете брать Крипто-про, берите именно бессрочную версию. Всё продавцы норовят продать подписку на год, которая всего в 2-3 раза дешевле бессрочной версии.
Пригласить эксперта
Типо того.
Благо есть ломанные версии
Да
Вы конечно не обязаны его покупать, но пользоваться подписью без него не сможете.
Изучаю вопрос работы с ЭЦП, которую теперь можно получить “бесплатно”
А почему бесплатно в кавычках? Ее действительно делают бесплатно.
нужно установить плагин в браузер, который в свою очередь хочет иметь Crypto Pro, которая платная.
Плагину Crypto Pro не нужен, он будет работать и без него прекрасно. Crypto Pro нужен для использования подписи.
То есть для работы с бесплатной КЭП ЭЦП от налоговой нужно купить и Носитель, и лицензию КриптоПро?
Разумеется.
16 сент. 2022, в 16:02
500 руб./в час
16 сент. 2022, в 15:37
1000 руб./за проект
16 сент. 2022, в 15:19
700000 руб./за проект
Минуточку внимания
Форум КриптоПро
»
Общие вопросы
»
Общие вопросы
»
Лицензирование Криптопро CSP в составе других продктов
mnemonicator Оставлено | |
Здравствуйте. Меня интересует следующий вопрос, мы приобритаем лицензии с ЭЦП на доступ к платфрме Контур Диадок и в составе пакета так же идет лицензия на Криптопро CSP. При установке ПО необходимого для работы Контур Диадок происходит установка и программы Криптопро CSP, при этом, нам не предоставляют лицензионный ключ, а используют некий параметр реестра для того, чтобы ввод ключа не был необходим. Так же, в письме, представитель компании Контур написал следующее, цитирую – Отвечаю на вопрос Почему сертификат содержащий КриптоПро можно устанавливать на несколько устройств (число не ограничено)? В моём понимании, мы можем поизвести установку КриптоПро на 100 компьютерах. Это действительно так и поставщики таких сервисов как Контур могут распространять ваше ПО на таких условиях? Спасибо. | |
Андрей * Оставлено | |
Здравствуйте. Встроенная в сертификат лицензия никуда не устанавливается. Она даёт право работать на любом РМ с таким сертификатом. Если будет сертификат без встроенной – то необходимо покупать отдельно лицензию на каждое рабочее место. | |
mnemonicator Оставлено | |
Хорошо, уточняющий вопрос. Лицензия, которая идет с сертификатом (выданым на конкретного человека) может быть использована этим сотрудником на нескольких рабочих местах или же лицензия привязана к 1 рабочему месту? | |
Андрей * Оставлено | |
Автор: mnemonicator Хорошо, уточняющий вопрос. Лицензия, которая идет с сертификатом (выданым на конкретного человека) может быть использована этим сотрудником на нескольких рабочих местах или же лицензия привязана к 1 рабочему месту? Да, выше ответ. | |
Из нашей статьи вы узнаете:
Для заверения документов цифровой подписью необходимо наличие криптопровайдера. Он обеспечивает защиту данных от внесения изменений. Для использования криптопровайдера КриптоПро необходимо наличие лицензии, которая может быть встроенной или идти отдельно.
Сертификат со встроенной лицензией
Для работы предварительно надо установить открытый ключ в закрытый. В этом случае не требуется дополнительной покупки лицензии на программное обеспечение, но перед началом использования важно проверить версию вашего ПО. Для этого перейдите по следующему пути: меню «Пуск» — «Панель управления» — «КриптоПро CSP». Далее — во вкладку «Общие» и проконтролируйте, чтобы версия была не ниже 4.0 (если необходимо, то выполните обновление).
Сертификат без встроенной лицензии
Здесь порядок действий несколько длиннее. Для начала надо найти приложение к договору, который вы получили вместе с криптопровайдером. Там должен содержаться уникальный серийный номер (обычно его отправляют по электронной почте или прикрепляют к комплекту установочных файлов). Непосредственно ввод ключа можно выполнить двумя способами.
Способ № 1:
- перейдите по пути: «Пуск» — «Программы» — «КриптоПро» — «КриптоПро PKI»;
- откройте пункт «Управление лицензиями» (для этого сделайте два клика мышкой);
- найдите пункт «КриптоПро CSP» и кликните по нему левой кнопкой;
- выберите в выпавшем меню пункт «Все задачи» — «Ввести серийный номер»;
- укажите полученный ключ.
Способ № 2.
Вариант подходит при покупке прав использования ПО в виде файла с расширением .lic.
Выполните следующие действия:
- перейдите по пути: «Пуск» — «Программы» — «КриптоПро» — «КриптоПро PKI»;
- откройте пункт «Управление лицензиями» (для этого сделайте два клика мышкой);
- выберите пункт «Установить лицензионный файл».
Если всё прошло в штатном режиме, то появится окно с указанием основной информации о пользователе, срока действия продукта. При появлении ошибок проверьте соответствие версии программного обеспечения (должна совпадать с той, для которой предоставлен лицензионный ключ), проконтролируйте правильность ручного ввода ключа.
Где купить КриптоПро
Если вам необходимо приобрести или продлить лицензию на использование «КриптоПро», то обращайтесь к нам в «Астрал-М». Мы являемся официальным партнёром разработчика (информацию о нашей компании, как о партнёре, можно найти на официальном сайте КриптоПро в разделе «Партнёры»). У нас вы сможете приобрести не только электронную подпись, но и криптопровайдер КриптоПро по отличной цене. Для приобретения заполните форму обратной связи на нашем сайте, чтобы наш менеджер связался с вами.
Общие сведения
КриптоПро .NET – программный продукт, позволяющий использовать средство криптографической защиты информации (СКЗИ) КриптоПро CSP на платформе Microsoft .NET Framework. КриптоПро .NET является новой версией существовавшего ранее программного продукта КриптоПро Sharpei и реализует набор интерфейсов для доступа к криптографическим операциям .NET Cryptographic Provider:
- хэширование;
- подпись;
- шифрование;
- MAC;
- генерация ключей и т.д.
Кроме того КриптоПро .NET позволяет использовать стандартные классы Microsoft для высокоуровневых операций:
- разбор сертификата;
- построение и проверка цепочки сертификатов;
- обработка CMS сообщений;
- установление защищенного обмена через SSL/TLS, HTTPS и FTPS;
- XML подпись и шифрование.
КриптоПро .NET состоит из двух частей:
- КриптоПро .NET – клиентский модуль для ОС Windows;
- КриптоПро .NET SDK – комплект разработчика, состоящий из документации, примеров и библиотек.
КриптоПро .NET обеспечивает применение всех алгоритмов, реализуемых КриптоПро CSP.
Сценарии использования
- Разработка приложений и веб-сервисов, в которых требуется использование российских криптоалгоритмов, на .NET Framework;
- Подпись и проверка подписи SOAP сообщений для взаимодействия информационных систем в единой системе межведомственного электронного взаимодействия;
- Пакетная подпись документов XPS и Microsoft Office (соответствующие примеры кода входят в состав КриптоПро .NET SDK);
- Подпись и проверка подписи с использованием Microsoft XPS Viewer;
- Защита соединений Microsoft Lync 2010 с использованием российских криптоалгоритмов;
- Использование российских криптоалгоритмов в службах федеративной аутентификации (AD FS, WIF, CardSpace и т.п.).
Документация
Документация на КриптоПро .NET SDK включена в дистрибутив и доступна на портале для разработчиков cpdn.
Вопросы встраивания и использования можно обсудить на форуме.
Лицензирование
Существует два вида лицензий КриптоПро .NET:
- Клиентская лицензия – предоставляет право установки и эксплуатации одной копии продукта на компьютере под управлением клиентской версии ОС Windows (XP/Vista/7/8/8.1/10);
- Серверная лицензия – предоставляет право установки и эксплуатации одной копии продукта на компьютере под управлением серверной версии ОС Windows (2003/2003 R2/2008/2008 R2/2012/2012 R2/2016/2019).
КриптоПро .NET SDK распространяется на бесплатной основе в составе КриптоПро SDK.
Системные требования
КриптоПро .NET функционирует на платформах Microsoft Windows 2000 и выше (x86 и x64) под управлением Microsoft .NET Framework 2.0 и выше и требует установленного КриптоПро CSP версии 2.0 и выше.
Для КриптоПро .NET SDK требуется наличие на компьютере установленного КриптоПро .NET.
Сертификаты
КриптоПро .NET использует сертифицированное ФСБ России средство криптографической защиты КриптоПро CSP.
Загрузить “КриптоПро .NET”
Заказать “КриптоПро .NET”
- Страница для печати
Из нашей статьи вы узнаете:
ЭЦП — довольно сложный цифровой продукт, обращение с которым в определенных ситуациях может потребовать некоторых навыков и знаний. Например, в ходе установки сертификатов ЭП посредством «КриптоПро» после выбора соответствующего ключевого контейнера нередко выдаются неприятные сообщения об ошибке вследствие отсутствия открытого шифровочного ключа, который необходим для обеспечения информационной безопасности, без чего система не будет принимать ЭЦП.
Такую ошибку несложно устранить без вызова специалиста или обращения в службу поддержки. Алгоритм действий, направленных на решение этой проблемы, приводится ниже.
Что может послужить причиной такой ошибки
Всплывающее окно со злополучным сообщением об ошибке появляется на экранах пользователей в тех случаях, если система не смогла обнаружить соответствующий ключ на носителе. Такая ситуация происходит при следующих действиях пользователей:
- установка сертификата впервые;
- экспортирование данных на внешний носитель;
- попытка просмотра ключей в контейнерах ключей;
- загрузка информации на компьютер извне.
В целях устранения ошибки обычно бывает достаточно произвести корректную ручную переустановку сертификата.
Решение ошибки: отсутствие электронного сертификата в контейнере закрытого ключа
Для начала запускаем «КриптоПро» нажатием кнопки «Пуск». Затем выбираем «Настройку», в возникающем на мониторе окне заходим в опцию панели управления, далее «сервис – установить личный сертификат».
Далее, через кнопку «обзор» указываем путь, где сохранен открытый ключ – файл с расширением *.cert или *.crt
Жмём «Далее», в мастере установки сертификата мы увидим путь, который указывали до нашего сертификата.
Нам отображается информация, содержащаяся в открытом ключе на пользователя, жмём «далее»
В следующем окне можно воспользоваться двумя путями поиска нужного контейнера закрытого ключа:
- «найти контейнер автоматически
- вручную через «обзор»
В первом случае КриптоПро на основе данных из открытого ключа подберет закрытый, в случае с ручным поиском нужно будет знать название закрытого ключа, чтобы выбрать его для установки
Самый простой вариант выбрать автоматический поиск, затем после «обнаружения» необходимого контейнера, мы увидим заполненную строчку с его именем и после жмём «Далее»
Личный сертификат пользователя всегда устанавливается в хранилище «Личное», можно выбрать как вручную, так и КриптоПро может сделать это за вас по умолчанию, затем подтверждаем установку цепочки сертификатов и жмём «Далее»
>
В случае успешной установки КриптоПро выдаст окно с информацией об окончании процедуры и жмём «Готово»
Затем появится окно с подтверждением данной операции, жмём «ДА»
В следующем окне увидим информацию о том, что процесс окончен успешно. Сертификат установлен в контейнер закрытого ключа.
Особенности версий КриптоПро
С января 2019 года квалифицированные сертификаты могут выпускаться только по ГОСТ 2012, выпуск по другому ГОСТу прекращен. Мы об этом писали ранее в статье. Важно помнить, что версии криптопро на ГОСТ 2012 работают только с версии 4.0 и выше. Все старые версии КриптоПро, для нормальной работы, потребуется обновить или заменить на актуальную. Сделать это нужно не позднее 31 декабря 2019 года.
amars Оставлено | |
как программно устанавливать ключи на .net ? | |
amars Оставлено | |
есть такая библиотека atcl.dll | |
Андрей Писарев Оставлено | |
Автор: amars как программно устанавливать ключи на .net ? В каком формате ключи? https://www.cryptopro.ru/downloads Есть такое решение: | |
amars Оставлено | |
amars Оставлено | |
получается у меня есть файл pfx криптопрошный. его надо в систему установить. ключ для работы со смев. программно на .net | |
amars Оставлено | |
тишина…. почему когда я делаю так X509Certificate2 x509 = new X509Certificate2(); у меня выходит окно ” Задайте пароль для создаваемого контейнера ” ? как от него избавиться ??????? | |
Максим Коллегин Оставлено | |
Этот интерфейс не позволяет использовать CSP в тихом режиме. Кроме пароля ещё местонахождение будущего контейнера может спрашиваться. | |
amars Оставлено | |
скажите, пожалуйста, а что позволяет? | |
Максим Коллегин Оставлено | |
Сходу не готов ответить. А какую задачу решаете? Почему появляется необходимость импорта pfx в тихом режиме? | |
amars Оставлено | |
есть необходимость подключать к нашей системе сразу несколько организаций. и у каждой организации свой ключ для работы в СМЭВ. вот… | |
Максим Коллегин Оставлено | |
А если не указывать X509KeyStorageFlags.PersistKeySet – должно же работать без окон? Только придется импортировать pfx перед каждой операцией. | |
amars Оставлено | |
этот флаг скрывает только мастер импорта сертификатов. т е он не помогает. | |
Максим Коллегин Оставлено | |
Постараюсь посмотреть внимательнее, кажется, что должно работать. | |
Максим Коллегин Оставлено | |
Посмотрел. | |
amars Оставлено | |
а вы можете привести пример как правильно использовать PKCS12_NO_PERSIST_KEY? | |
amars Оставлено | |
у меня в принципе все получилось сделать, Отредактировано пользователем 21 сентября 2016 г. 17:20:16(UTC) | |
Максим Коллегин Оставлено | |
Флаг PKCS12_NO_PERSIST_KEY оказался недостаточно протестированным в нашем коде – завтра постараюсь предоставить сборку с исправлением. Какую версию CSP используете? Отредактировано пользователем 21 сентября 2016 г. 20:56:44(UTC) | |
amars Оставлено | |
amars Оставлено | |
у вас есть для меня что-нибудь? | |
Максим Коллегин Оставлено | |
Попробуйте с последней выложенной версией CSP 3.9 R2. | |
Александр Я. Оставлено | |
На сайте Автор: ” https://support.cryptopr…sp-v-kriptopro-csp” Дополнительно: С какими конкретно Рутокен ЭЦП это работает и надо как-то по особому это настраивать при запросе сертификата в УЦ? P.S. Это результат работы ТК26 или случайно получилось? Отредактировано пользователем 12 мая 2021 г. 16:54:22(UTC) | |
Агафьин Сергей Оставлено | |
Автор: Александр Я. На сайте Автор: ” https://support.cryptopr…sp-v-kriptopro-csp” Дополнительно: С какими конкретно Рутокен ЭЦП это работает и надо как-то по особому это настраивать при запросе сертификата в УЦ? P.S. Это результат работы ТК26 или случайно получилось? Подойдет любой Рутокен ЭЦП 2.0. С уважением, | |
Павел Заика Оставлено | |
Добрый день! | |
Александр Я. Оставлено | |
Автор: Агафьин Сергей Подойдет любой Рутокен ЭЦП 2.0. Рутокен ЭЦП 2.0 должен использоваться в режиме “пассивного USB-токена” или можно и с “неизвлекаемым ключом” (т.к. Vipnet точно не поддерживает SESPAKE)? | |
Агафьин Сергей Оставлено | |
Автор: Александр Я. Автор: Агафьин Сергей Подойдет любой Рутокен ЭЦП 2.0. Рутокен ЭЦП 2.0 должен использоваться в режиме “пассивного USB-токена” или можно и с “неизвлекаемым ключом” (т.к. Vipnet точно не поддерживает SESPAKE)? Не знаю, как это выглядит в VipNet CSP. Речь об аппаратной криптографии. С уважением, | |
Александр Я. Оставлено | |
Автор: Агафьин Сергей Не знаю, как это выглядит в VipNet CSP. Речь об аппаратной криптографии. Тогда получается что можно работать с Рутокен ЭЦП 2.0 вообще без “CSP”, а через PKCS#11 (например с BouncyCastle и не надо заморачиваться с конвертацией нестандартизованных закрытых ключей cryptopro)? | |
Агафьин Сергей Оставлено | |
Автор: Александр Я. Автор: Агафьин Сергей Не знаю, как это выглядит в VipNet CSP. Речь об аппаратной криптографии. Тогда получается что можно работать с Рутокен ЭЦП 2.0 вообще без “CSP”, а через PKCS#11 (например с BouncyCastle и не надо заморачиваться с конвертацией нестандартизованных закрытых ключей cryptopro)? С Рутокен ЭЦП 2.0 всегда можно было работать без CSP: С уважением, | |
Приобретение лицензии через сайт КриптоПро
Перейдите по ссылке, либо на главной странице сайта в разделе «Купить» нажмите Продукты компании, обновления и доп. ПО:
Выберите один из трех вариантов: Юридические лица, Индивидуальные предприниматели, Физические лица или Иностранные физические лица:
В открывшемся разделе сайта в левом столбце располагается прайс-лист с перечнем продукции КриптоПро. В списке выберите вашу версию КриптоПро CSP:
После выбора откроется таблица с перечнем лицензий и ценами на них. В столбце «Количество» напротив необходимой строки укажите количество позиций, которое вы планируете приобрести и нажмите кнопку Добавить в заказ:
Ниже откроется таблица «Ваш заказ», в которой указаны добавленные в заказ позиции и итоговая сумма заказа. Проверьте ваш заказ, при необходимости удалите лишние позиции, нажав соответствующую кнопку. Выберите способ доставки, а так же при необходимости укажите комментарий к заказу. Далее нажмите кнопку Оформить заказ:
Откроется регистрационная форма, в которой необходимо заполнить все поля. После заполнения полей регистрационной формы проставьте флажок «Я подтверждаю свое согласие на передачу информации…» и нажмите кнопку Разместить заказ:
В случае если все данные заполнены корректно, откроются дальнейшие инструкции по размещенному заказу.
Немного покодим
Потребуется 2 COM библиотеки: “CAPICOM v2.1 Type Library” и “Crypto-Pro CAdES 1.0 Type Library”. Они содержат необходимые объекты для создания УКЭП.
В этом примере будет подписываться BASE64 строка, содержащая в себе PDF-файл. Немного доработав код можно будет подписать hash-значение этого фала.
Основной код для подписания был взят со страниц Подпись PDF с помощью УЭЦП- Page 2 (cryptopro.ru) и Подпись НЕОПРЕДЕЛЕНА при создании УЭЦП для PDF на c# (cryptopro.ru), но он использовался для штампа подписи на PDF документ. Код из этого гайда переделан под сохранение файла подписи в отдельный файл.
Условно процесс можно поделить на 4 этапа:
Поиск сертификата в хранилище – я использовал поиск по отпечатку в хранилище пользователя;
Чтение байтов подписанного файла;
Сохранение файла подписи рядом с файлом.
using CAdESCOM;
using CAPICOM;
using System;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
public static void Main()
{
//Сертификат для подписи
X509Certificate2 gostCert = GetX509Certificate2("отпечаток");
//Файл, который предстоит подписать
byte[] fileBytes = File.ReadAllBytes("C:\\Тестовое заявление.pdf");
//Файл открепленной подписи
byte[] signatureBytes = SignWithAdvancedEDS(fileBytes, gostCert);
//Сохранение файла подписи
File.WriteAllBytes("C:\\Users\\mikel\\Desktop\\Тестовое заявление.pdf.sig", signatureBytes);
}
//Поиск сертификата в хранилище
public static X509Certificate2 GetX509Certificate2(string thumbprint)
{
X509Store store = CreateStoreObject("My", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection =
store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
X509Certificate2Enumerator enumerator = certCollection.GetEnumerator();
X509Certificate2 gostCert = null;
while (enumerator.MoveNext())
gostCert = enumerator.Current;
if (gostCert == null)
throw new Exception("Certificiate was not found!");
return gostCert;
}
//Создание УКЭП
public static byte[] SignWithAdvancedEDS(byte[] fileBytes, X509Certificate2 certificate)
{
string signature = "";
try
{
string tspServerAddress = @"http://qs.cryptopro.ru/tsp/tsp.srf";
CPSigner cps = new CPSigner();
cps.Certificate = GetCAPICOMCertificate(certificate.Thumbprint);
cps.Options = CAPICOM_CERTIFICATE_INCLUDE_OPTION.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN;
cps.TSAAddress = tspServerAddress;
CadesSignedData csd = new CadesSignedData();
csd.ContentEncoding = CADESCOM_CONTENT_ENCODING_TYPE.CADESCOM_BASE64_TO_BINARY;
csd.Content = Convert.ToBase64String(fileBytes);
//Создание и проверка подписи CAdES BES
signature = csd.SignCades(cps, CADESCOM_CADES_TYPE.CADESCOM_CADES_BES, true, CAdESCOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64);
csd.VerifyCades(signature, CADESCOM_CADES_TYPE.CADESCOM_CADES_BES, true);
//Дополнение и проверка подписи CAdES BES до подписи CAdES X Long Type 1
//(вторая подпись остается без изменения, так как она уже CAdES X Long Type 1)
signature = csd.EnhanceCades(CADESCOM_CADES_TYPE.CADESCOM_CADES_X_LONG_TYPE_1, tspServerAddress, CAdESCOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64);
csd.VerifyCades(signature, CADESCOM_CADES_TYPE.CADESCOM_CADES_X_LONG_TYPE_1, true);
}
catch (Exception ex)
{
throw ex;
}
return Convert.FromBase64String(signature);
}
Пробный запуск
Для подписания возьмем PDF-документ, который содержит надпись “Тестовое заявление.”:
Далее запустим программу и дождемся подписания файла:
Готово. Теперь можно приступать к проверкам.
Проверка в КриптоАРМ
Время создания ЭП заполнено:
Штамп времени на подпись есть:
Доказательства подлинности также заполнены:
В протоколе проверки есть блоки “Доказательства подлинности”, “Штамп времени на подпись” и “Время подписания”:
Важно отметить, что серийный номер параметров сертификата принадлежит TSP-сервису http://qs.cryptopro.ru/tsp/tsp.srf
Проверка на Госуслугах
Проверка в Контур. Крипто
Что имеем на входе?
КриптоПро CSP версии 5.0 – для поддержки Российских криптографических алгоритмов (подписи, которые выпустили в аккредитованном УЦ в РФ)
КриптоПро TSP Client 2.0 – нужен для штампа времени
КриптоПро OCSP Client 2.0 – проверит не отозван ли сертификат на момент подписания
КриптоПро .NET Client – таков путь
Любой сервис по проверке ЭП – я использовал Контур.Крипто как основной сервис для проверки ЭП и КриптоАРМ как локальный. А еще можно проверить ЭП на сайте Госуслуг
КЭП по ГОСТ Р 34.11-2012/34.10-2012 256 bit, которую выпустил любой удостоверяющий центр
Лицензирование ПО и версии
КриптоПро CSP версии 5.0 – у меня установлена версия 5.0.11944 КС1, лицензия встроена в ЭП.
КриптоПро TSP Client 2.0 и КриптоПро OCSP Client 2.0 – лицензии покупается отдельно, а для гайда мне хватило демонстрационного срока.
КриптоПро .NET Client версии 1.0.7132.2 – в рамках этого гайда я использовал демонстрационную версию клиентской части и все действия выполнялись локально. Лицензию на сервер нужно покупать отдельно.
Контур.Крипто бесплатен, но требует регистрации. В нем также можно подписать документы КЭП, УКЭП и проверить созданную подпись загрузив ее файлы.
Сборка утилиты конвертирования ключа
Далее сборка исходников описана для Linux версии.
Версию для Windows можно скачать отсюда там же есть сертификаты и закрытый ключ для тестирования, для сборки потребуется бесплатный компилятор Borland C++ 5.5
Компиляция OpenSSL библиотеки
После скачивания и распаковки исходных текстов openssl в целевой директории выполняем команды:
./config
make
Получаем готовую библиотеку libcrypto.a в текущей директории.
Также потребуются заголовочные файлы из директорий engines/ccgost и include.
Компиляция privkey
gcc -o privkey -Iengines/ccgost -Iinclude privkey.c libcrypto.a -pthread -ldl
Формирование файла закрытого ключа private. key
./privkey /mnt/usbflash/lp-9a0fe.000
Тестовый закрытый ключ в криптоконтейнере lp-9a0fe.000, сертификат открытого ключа signer.cer и другие файлы для тестирования можно взять отсюда
Получаем результат работы:
-----BEGIN PRIVATE KEY-----
MEYCAQAwHAYGKoUDAgITMBIGByqFAwICJAAGByqFAwICHgEEIwIhAKzsrv/l1Uwk
uzph/LQN9mux0Jz0yaW21kOYEFv0Xyut
-----END PRIVATE KEY-----
Cохраняем в private.key
Пользуемся закрытым ключом private. key для подписывания файла file. txt
openssl cms -sign -inkey private.key -in file.txt -CAfile CA.cer -signer signer.cer -engine gost -out test.sign -outform DER -noattr -binary
Проверяем подпись
openssl cms -verify -content file.txt -in test.sign -CAfile CA.cer -signer signer.cer -engine gost -inform DER -noattr -binary
Все работает просто замечательно!
Спасибо за внимание. Это была моя первая статья на хабре.
Done.
Гайд написан с исследовательской целью – проверить возможность подписания документов УКЭП с помощью самописного сервиса на .NET Core 3.1 с формированием штампов подлинности и времени подписания документов.
Безусловно это решение не стоит брать в работу “как есть” и нужны некоторые доработки, но в целом оно работает и подписывает документы подписью УКЭП.
Соберем проект с поддержкой ГОСТ Р 34. 11-2012 256 bit
Гайд разделен на несколько этапов. Основная инструкция по сборке опубликована вместе с репозиторием DotnetCoreSampleProject – периодически я буду на нее ссылаться.
Первым делом создадим новую папку
… и положим туда все необходимое.
Инструкция делится на 2 этапа – мне пришлось выполнить оба, чтобы решение заработало. В папку добавьте подпапки .\runtime и .\packages
I – Сборка проекта без сборки corefx для Windows
Установите КриптоПро 5.0 и убедитесь, что у вас есть действующая лицензия. – для меня подошла втроенная в ЭП;
Установите core 3.1 sdk и runtime и распространяемый пакет Visual C++ для Visual Studio 2015 обычно ставится вместе со студией; прим.: на II этапе мне пришлось через установщик студии поставить дополнительное ПО для разработки на C++ – сборщик требует предустановленный DIA SDK.
Задайте переменной среды DOTNET_MULTILEVEL_LOOKUP значение 0 – не могу сказать для чего это нужно, но в оригинальной инструкции это есть;
package_windows_debug.zip распакуйте в .\packages
runtime-debug-windows.zip распакуйте в .\runtime
Добавьте источник пакетов NuGet в файле %appdata%\NuGet\NuGet.Config – источник должен ссылаться на путь .\packages в созданной вами папке. Пример по добавлению источника есть в основной инструкеии. Для меня это не сработало, поэтому я добавил источник через VS Community;
git clone https://github.com/CryptoProLLC/NetStandard.Library New-Item -ItemType Directory -Force -Path "$env:userprofile\.nuget\packages\netstandard.library" Copy-Item -Force -Recurse ".\NetStandard.Library\nugetReady\netstandard.library" -Destination "$env:userprofile\.nuget\packages\"
Склонируйте репизиторий DotnetCoreSampleProject в .\
Измените файл .\DotnetSampleProject\DotnetSampleProject.csproj – для сборок System.Security.Cryptography.Pkcs.dll и System.Security.Cryptography.Xml.dll укажите полные пути к .\runtime;
Перейдите в папку проекта и попробуйте собрать решение. Я собирал через Visual Studio после открытия проекта.
II – Сборка проекта со сборкой corefx для Windows
Выполните 1-3 и 6-й шаги из I этапа;
Склонируйте репозиторий corefx в .\
Выполните сборку запустив .\corefx\build.cmd – на этом этапе потребуется предустановленный DIA SDK
Выполните шаги 5, 7-9 из I этапа. Вместо условного пути .\packages укажите .\corefx\artifacts\packages\Debug\NonShipping, а вместо .\runtime укажите .\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Debug-x64
На этом месте у вас должно получиться решение, которое поддерживает ГОСТ Р 34.11-2012 256 bit.
Читаем закрытый ключ и конвертируем
Файл privkey.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>
#include "gost_lcl.h"
/* Convert little-endian byte array into bignum */
BIGNUM *reverse32bn(char *b, BN_CTX *ctx)
{
BIGNUM *res;
char buf[32];
BUF_reverse(buf, b, 32);
res = BN_bin2bn(buf, 32, BN_CTX_get(ctx));
OPENSSL_cleanse(buf, sizeof(buf));
return res;
}
void xor_material(char *buf36, char *buf5C, char *src)
{
int i;
for(i = 0; i < 32; i++)
{
buf36[i] = src[i] ^ 0x36;
buf5C[i] = src[i] ^ 0x5C;
}
}
int make_pwd_key(char *result_key, char *start12, int start12_len, char *passw)
{
int result;
int i;
char pincode4[1024];
int pin_len;
char current[32];
char material36[32];
char material5C[32];
char hash_result[32];
gost_hash_ctx ctx;
init_gost_hash_ctx(&ctx, &GostR3411_94_CryptoProParamSet);
memset(pincode4, 0, sizeof(pincode4));
pin_len = strlen(passw);
if (pin_len*4 > sizeof(pincode4)) { result = 1; goto err; }
for(i = 0; i < pin_len; i++)
pincode4[i*4] = passw[i];
start_hash(&ctx);
hash_block(&ctx, start12, start12_len);
if (pin_len)
hash_block(&ctx, pincode4, pin_len * 4);
finish_hash(&ctx, hash_result);
memcpy(current, (char*)"DENEFH028.760246785.IUEFHWUIO.EF", 32);
for(i = 0; i < (pin_len?2000:2); i++)
{
xor_material(material36, material5C, current);
start_hash(&ctx);
hash_block(&ctx, material36, 32);
hash_block(&ctx, hash_result, 32);
hash_block(&ctx, material5C, 32);
hash_block(&ctx, hash_result, 32);
finish_hash(&ctx, current);
}
xor_material(material36, material5C, current);
start_hash(&ctx);
hash_block(&ctx, material36, 32);
hash_block(&ctx, start12, start12_len);
hash_block(&ctx, material5C, 32);
if (pin_len)
hash_block(&ctx, pincode4, pin_len * 4);
finish_hash(&ctx, current);
start_hash(&ctx);
hash_block(&ctx, current, 32);
finish_hash(&ctx, result_key);
result = 0; //ok
err:
return result;
}
BIGNUM *decode_primary_key(char *pwd_key, char *primary_key, BN_CTX *bn_ctx)
{
BIGNUM *res;
char buf[32];
gost_ctx ctx;
gost_init(&ctx, gost_cipher_list->sblock);
gost_key(&ctx, pwd_key);
gost_dec(&ctx, primary_key, buf, 4);
res = reverse32bn(buf, bn_ctx);
OPENSSL_cleanse(buf, sizeof(buf));
return res;
}
BIGNUM *remove_mask_and_check_public(char *oid_param_set8, BIGNUM *key_with_mask, BIGNUM *mask, char *public8, BN_CTX *ctx)
{
int result;
EC_KEY *eckey = NULL;
const EC_POINT *pubkey;
const EC_GROUP *group;
BIGNUM *X, *Y, *order, *raw_secret, *mask_inv;
char outbuf[32], public_X[32];
ASN1_OBJECT *obj;
int nid;
order = BN_CTX_get(ctx);
mask_inv = BN_CTX_get(ctx);
raw_secret = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
Y = BN_CTX_get(ctx);
if (!order || !mask_inv || !raw_secret || !X || !Y) { result = 1; goto err; }
obj = ASN1_OBJECT_create(0, oid_param_set8+1, *oid_param_set8, NULL, NULL);
nid = OBJ_obj2nid(obj);
ASN1_OBJECT_free(obj);
if (!(eckey = EC_KEY_new())) { result = 1; goto err; }
if (!fill_GOST2001_params(eckey, nid)) { result = 1; goto err; }
if (!(group = EC_KEY_get0_group(eckey))) { result = 1; goto err; }
if (!EC_GROUP_get_order(group, order, ctx)) { result = 1; goto err; }
if (!BN_mod_inverse(mask_inv, mask, order, ctx)) { result = 1; goto err; }
if (!BN_mod_mul(raw_secret, key_with_mask, mask_inv, order, ctx)) { result = 1; goto err; }
if (!EC_KEY_set_private_key(eckey, raw_secret)) { result = 1; goto err; }
if (!gost2001_compute_public(eckey)) { result = 1; goto err; }
if (!(pubkey = EC_KEY_get0_public_key(eckey))) { result = 1; goto err; }
if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { result = 1; goto err; }
store_bignum(X, outbuf, sizeof(outbuf));
BUF_reverse(public_X, outbuf, sizeof(outbuf));
if (memcmp(public_X, public8, 8) != 0) { result = 1; goto err; }
result = 0; //ok
err:
if (eckey) EC_KEY_free(eckey);
if (result == 0) return raw_secret;
return NULL;
}
int file_length(char *fname)
{
int len;
FILE *f = fopen(fname, "rb");
if (f == NULL) return -1;
fseek(f, 0, SEEK_END);
len = ftell(f);
fclose(f);
return len;
}
int read_file(char *fname, int start_pos, char *buf, int len)
{
int read_len;
FILE *f = fopen(fname, "rb");
if (f == NULL) return 1;
if (start_pos) fseek(f, start_pos, SEEK_SET);
read_len = fread(buf, 1, len, f);
fclose(f);
if (read_len != len) return 1;
return 0; //ok
}
int get_asn1_len(unsigned char *buf, int *size_hdr)
{
int n, i, res;
int pos = 0;
if ((buf[pos]&0x80) == 0) {
*size_hdr = 1;
return buf[pos];
}
n = buf[pos++]&0x7f;
res = 0;
for(i = 0; i < n; i++) {
res = res*256 + buf[pos++];
}
*size_hdr = n+1;
return res;
}
#define MAX_HEADER 20000
int read_container(char *fpath, int flag2, char *salt12, char *primary_key, char *masks_key, char *public8, char *oid_param_set8)
{
int result;
char primary_path[1024+30];
char masks_path[1024+30];
char header_path[1024+30];
char header_buf[MAX_HEADER];
int header_len;
int i, len, pos, size_hdr;
if (strlen(fpath)>1024) { result = 1; goto err; }
sprintf(header_path, "%s/header.key", fpath);
if (flag2 == 0)
{
sprintf(primary_path, "%s/primary.key", fpath);
sprintf(masks_path, "%s/masks.key", fpath);
}
else
{
sprintf(primary_path, "%s/primary2.key", fpath);
sprintf(masks_path, "%s/masks2.key", fpath);
}
if (read_file(primary_path, 4, primary_key, 32)) { result = 1; goto err; }
if (read_file(masks_path, 4, masks_key, 32)) { result = 1; goto err; }
if (read_file(masks_path, 0x26, salt12, 12)) { result = 1; goto err; }
header_len = file_length(header_path);
if (header_len < 0x42 || header_len > MAX_HEADER) { result = 1; goto err; }
if (read_file(header_path, 0, header_buf, header_len)) { result = 1; goto err; }
//------------- skip certificate ---------------------------
pos = 0;
for(i = 0; i < 2; i++)
{
get_asn1_len(header_buf+pos+1, &size_hdr);
pos += size_hdr+1;
if (pos > header_len-8) { result = 2; goto err; }
}
//------------------ get oid_param_set8 -----------------------
#define PARAM_SET_POS 34
if (memcmp(header_buf+pos+PARAM_SET_POS, "\x6\x7", 2) != 0) { result = 2; goto err; }
memcpy(oid_param_set8, header_buf+pos+PARAM_SET_POS+1, 8);
//------------------ get public8 -----------------------
result = 2; //not found
pos += 52;
for(i = 0; i < 3; i++)
{
len = get_asn1_len(header_buf+pos+1, &size_hdr);
if (len == 8 && memcmp(header_buf+pos, "\x8a\x8", 2) == 0)
{
memcpy(public8,header_buf+pos+2,8);
result = 0; //ok
break;
}
pos += len+size_hdr+1;
if (pos > header_len-8) { result = 2; goto err; }
}
err:
OPENSSL_cleanse(header_buf, sizeof(header_buf));
return result;
}
#define START_OID 0x12
#define START_KEY 0x28
unsigned char asn1_private_key[72] = {
0x30,0x46,2,1,0,0x30,0x1c,6,6,0x2a,0x85,3,2,2,0x13,0x30,0x12,6,7,0x11,
0x11,0x11,0x11,0x11,0x11,0x11,6,7,0x2a,0x85,3,2,2,0x1e,1,4,0x23,2,0x21,0
};
int main(int argc, char **argv)
{
int result;
char *container_path;
char *passw;
char salt12[12];
char primary_key[32];
char masks_key[32];
char public8[8];
char oid_param_set8[8];
BN_CTX *ctx;
BIGNUM *key_with_mask;
BIGNUM *mask;
BIGNUM *raw_key;
char pwd_key[32];
char outbuf[32];
ctx = BN_CTX_new();
if (argc == 2)
{
container_path = argv[1];
passw = "";
}
else
if (argc == 3)
{
container_path = argv[1];
passw = argv[2];
}
else
{
printf("get_private container_path [passw]\n");
result = 1;
goto err;
}
if (read_container(container_path, 0, salt12, primary_key, masks_key, public8, oid_param_set8) != 0 &&
read_container(container_path, 1, salt12, primary_key, masks_key, public8, oid_param_set8) != 0)
{
printf("can not read container from %s\n", container_path);
result = 2;
goto err;
}
make_pwd_key(pwd_key, salt12, 12, passw);
key_with_mask = decode_primary_key(pwd_key, primary_key, ctx);
OPENSSL_cleanse(pwd_key, sizeof(pwd_key));
mask = reverse32bn(masks_key, ctx);
raw_key = remove_mask_and_check_public(oid_param_set8, key_with_mask, mask, public8, ctx);
if (raw_key)
{
BIO *bio;
store_bignum(raw_key, outbuf, sizeof(outbuf));
memcpy(asn1_private_key+START_OID, oid_param_set8, 8);
memcpy(asn1_private_key+START_KEY, outbuf, 32);
//bio = BIO_new_file("private.key", "w");
bio = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT);
PEM_write_bio(bio, "PRIVATE KEY", "", asn1_private_key, sizeof(asn1_private_key));
BIO_free(bio);
OPENSSL_cleanse(outbuf, sizeof(outbuf));
OPENSSL_cleanse(asn1_private_key, sizeof(asn1_private_key));
result = 0; //ok
}
else
{
printf("Error check public key\n");
result = 3;
}
err:
BN_CTX_free(ctx);
OPENSSL_cleanse(salt12, sizeof(salt12));
OPENSSL_cleanse(primary_key, sizeof(primary_key));
OPENSSL_cleanse(masks_key, sizeof(masks_key));
return result;
}
Небольшой комментарий.
Основную работу выполняют следующие 3 функции:
1. Создаем ключ хранения исходя из 12-ти байтовой «соли» и пароля.
make_pwd_key(pwd_key, salt12, 12, passw);
2. Расшифровываем основной ключ на ключе хранения.
key_with_mask = decode_primary_key(pwd_key, primary_key, ctx);
3. Делим ключ с маской на маску.
raw_key = remove_mask_and_check_public(oid_param_set8, key_with_mask, mask, public8, ctx);
Но так как в библиотеке OpenSLL операция деления по модулю традиционно отсутствует, пользуемся операцией взятия обратного числа и умножением.
if (!BN_mod_inverse(mask_inv, mask, order, ctx)) { result = 1; goto err; }
if (!BN_mod_mul(raw_secret, key_with_mask, mask_inv, order, ctx)) { result = 1; goto err; }
Файл header. key
Из этого файла нам потребуется параметры электронной подписи CryptoProParamSet (подчеркнуто красным).
- GostR3410_2001_CryptoPro_A_ParamSet — 1.2.643.2.2.35.1
- GostR3410_2001_CryptoPro_B_ParamSet — 1.2.643.2.2.35.2
- GostR3410_2001_CryptoPro_C_ParamSet — 1.2.643.2.2.35.3
- GostR3410_2001_CryptoPro_XchA_ParamSet — 1.2.643.2.2.36.0
- GostR3410_2001_CryptoPro_XchB_ParamSet — 1.2.643.2.2.36.1
А также первые 8 байт открытого ключа (подчеркнуто) для контроля правильности чтения закрытого.
Файл masks. key
Содержит 32 байта маски ключа в формате Asn1, зашифрованного на ключе хранения pwd_key. Далее 12 байт «затравочной» информации для генерации ключа хранения pwd_key, если криптоконтейнер защищен паролем, то пароль также участвует в генерации ключа хранения.
Далее контрольная сумма (имитозащита) 4 байта. Контрольной информацией для простоты мы пользоваться не будем, общий контроль будет осуществляться путем генерации открытого ключа и сравнения первых 8 байт полученного ключа с соответствующим полем из файла header.key:
Ввод лицензии
После получения серийного номера, его необходимо ввести в программу. Для этого откройте КриптоПро CSP (Пуск → Все программы → КриптоПро → КриптоПро CSP или Пуск → Панель управления → КриптоПро CSP).
В открывшейся программе на вкладке Общие нажмите кнопку Ввод лицензии:
Заполните данные и введите полученный серийный номер СКЗИ КриптоПро CSP:
Ссылки на публичные источники
[1] CMS Advanced Electronic Signatures (CAdES) – https://tools.ietf.org/html/rfc5126#ref-ISO7498-2
[2] Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP) – https://www.ietf.org/rfc/rfc3161.txt
[3] X.509 Internet Public Key Infrastructure Online Certificate Status Protocol – OCSP – https://tools.ietf.org/html/rfc2560
[4] Усовершенствованная квалифицированная подпись — Удостоверяющий центр СКБ Контур (kontur.ru)
[5] Поддержка .NET Core (cryptopro.ru)
[6] http://qs.cryptopro.ru/tsp/tsp.srf – TSP-сервис КриптоПро
UPD1: Поменял в коде переменную, куда записываются байты файла подписи.
Также я забыл написать немного про подпись штампа времени – он подписывается сертификатом владельца TSP-сервиса. По гайду это ООО “КРИПТО-ПРО”:
UPD2: Про библиотеки CAdESCOM и CAPICOM
В ответ @kotov_a и @mayorovp– Все верно: для .NET Core 3.1 сборки System.Security.Cryptography.Pkcs.dll и System.Security.Cryptography.Xml.dll подменяются, так как поддержка этих алгоритмов в бета тестировании [5], а для .NET Framework 4.8 используется CryptoPro.Sharpei – он был перенесен в состав КриптоПро .NET. Последний, судя по информации с портала документации, работает только с .NET Framework.
Если создать пустой проект на .NET Core 3.1, подключив непропатченные библиотеки, то при обращении к закрытому ключу выпадет исключение “System.NotSupportedException” c сообщением “The certificate key algorithm is not supported.”:
<TargetFramework>netcoreapp3.1</TargetFramework>
...
<ItemGroup>
<COMReference Include="CAdESCOM">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>0</VersionMinor>
<VersionMajor>1</VersionMajor>
<Guid>e00b169c-ae7f-45d5-9c56-672e2b8942e0</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
<COMReference Include="CAPICOM">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>1</VersionMinor>
<VersionMajor>2</VersionMajor>
<Guid>bd26b198-ee42-4725-9b23-afa912434229</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
...
Но при использовании пропатченных библиотек это исключение не выпадает и с приватным ключем можно взаимодействовать:
<TargetFramework>netcoreapp3.1</TargetFramework>
...
<ItemGroup>
<Reference Include="System.Security.Cryptography.Pkcs">
<HintPath>.\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Debug-x64\System.Security.Cryptography.Pkcs.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Xml">
<HintPath>.\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Debug-x64\System.Security.Cryptography.Xml.dll</HintPath>
</Reference>
</ItemGroup>
...
Также код из гайда работает с .NET Framework 4.8 без использования пропатченных библиотек, но вместо обращения к пространству имен “System.Security.Cryptography”, которое подменяется пропатченными библиотеками для .NET Core, CSP Gost3410_2012_256CryptoServiceProvider будет использован из пространства имен “CryptoPro.Sharpei”:
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
...
<ItemGroup>
<COMReference Include="CAdESCOM">
<Guid>{E00B169C-AE7F-45D5-9C56-672E2B8942E0}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="CAPICOM">
<Guid>{BD26B198-EE42-4725-9B23-AFA912434229}</Guid>
<VersionMajor>2</VersionMajor>
<VersionMinor>1</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="CERTENROLLLib">
<Guid>{728AB348-217D-11DA-B2A4-000E7BBB2B09}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
...
Так, а что надо на выходе?
А на выходе надо получить готовое решение, которое сделает отсоединенную ЭП в формате .sig со штампом времени на подпись и доказательством подлинности. Для этого зададим следующие критерии:
ЭП проходит проверку на портале Госуслуг, через сервис для подтверждения подлинности ЭП формата PKCS#7 в электронных документах;
КриптоАРМ после проверки подписи
Заполнит поле “Время создания ЭП” – в конце проверки появится окно, где можно выбрать ЭП и кратко посмотреть ее свойства
В информации о подписи и сертификате (двойной клик по записе в таблице) на вкладке “Штампы времени” в выпадающем списке есть оба значения и по ним заполнена информация:
В протоколе проверки подписи есть блоки “Доказательства подлинности”, “Штамп времени на подпись” и “Время подписания”. Для сравнения: если документ подписан просто КЭП, то отчет по проверке будет достаточно коротким в сравнении с УКЭП.
Контур.Крипто при проверке подписи выдаст сообщение, что совершенствованная подпись подтверждена, сертификат на момент подписания действовал и указано время создания подпись: