- Почему криптопро не видит ключ эцп
- Введение
- · выбор сертификата
- Как посмотреть сертификат
- Копируем сертификат эцп через «инструменты криптопро»
- Криптопро csp: как установить сертификат ключа проверки эп в контейнер – подготовка
- Криптопро csp: пин код для контейнера: несколько важных замечаний
- Криптопро csp: создаем пароль для контейнера
- Криптопро вставлен другой носитель: как исправить
- Недостаточно прав для выполнения операции в криптопро
- Удаление веток системного реестра
- Что делать, если система запомнила сервисные пароли и не находит контейнер
- Правильная установка сертификата
- Проверка сертификата на предмет конфликта со сторонним криптопровайдером
- Каким образом проверить флеш-накопитель на наличие контейнера
- Выполнение записи с флеш-накопителя напрямую, если нет открытого ключа
- Заключение
- Читаем закрытый ключ и конвертируем
Почему криптопро не видит ключ эцп
КриптоПро CSP — самый популярный криптографический софт на российском рынке. Большинство торговых площадок и автоматизированных госсистем работают только с этим криптопровайдером. Программное обеспечение распространяется на безвозмездной основе разработчиком и через дистрибьюторскую сеть, а за лицензию придется платить. При покупке квалифицированной ЭП (КЭП) клиенты получают набор средств:
- закрытый и открытый ключи;
- сертификат ключа проверки электронной подписи (СКПЭП, СЭП) — привязан к открытому ключу;
- физический носитель, на который записываются все перечисленные средства.
Каждый раз, когда владельцу СЭП нужно подписать цифровой файл, он подключает USB-носитель к ПК и вводит пароль (двухфакторная идентификация). Возможен и другой путь — записать все компоненты в реестр ПК и пользоваться ими без физического криптоключа.
В работе с ЭП возникают такие ситуации, когда пользователь пытается заверить документ в интернете или в специальном приложении, открывает список ключей и не видит СЭП. Проблема может быть спровоцирована следующими факторами:
Введение
Мне постоянно приходится иметь дело с сертификатами, токенами, закрытыми ключами, криптопровайдерами и прочим. Сейчас все завязано на это – банкинг, сдача отчетности в разные гос органы, обращения опять же в эти органы, в том числе и физ лиц. В общем, с этой темой рано или поздно придется познакомиться многим.
- Перенести или скопировать контейнер закрытого ключа через стандартную оснастку CryptoPro в панели управления. Это самый простой и быстрый способ, если у вас не много сертификатов и ключей. Если же их несколько десятков, а это не такая уж и редкость, то такой путь вам не подходит.
- Скопировать сертификаты и ключи непосредственно через перенос самих исходных файлов и данных, где все это хранится. Объем работы одинаков и для 5 и для 50-ти сертификатов, но требуется больше усилий и знаний.
Я опишу оба этих способа, но подробно остановлюсь именно на втором способе. В некоторых ситуациях он является единственно возможным.
Важное замечание. Я буду переносить контейнеры закрытого ключа, которые хранятся в реестре. Если вы храните их только на токене, то переносить контейнеры вам не надо, только сертификаты.
· выбор сертификата
1. В окне «Мастер установки личного сертификата»
нажмите кнопку «Далее»
2. В следующем окне «Расположение файла сертификата»
нажмите кнопку «Обзор»
и укажите расположение личного сертификата (файл Фамилия имя отчество. cer
на вашей дискете)
Если на
flash
не обнаружено сертификата открытого ключа:
· Уточнить не было ли казначейством выдано других дискет, носителей, на которых может содержаться данный сертификат. Сертификат открытого ключа можно скопировать на компьютер (рабочий стол), а при установке личного сертификата должен быть вставлен flash с контейнером закрытого ключа (папка вида с названием, где на конце «.000»), а открытый ключ подтягиваем с рабочего стола.
· Если сертификат устанавливался ранее, то можно выгрузить сертификат открытого ключа из хранилища сертификатов в IE.
· Необходимо уточнить формировался ли запрос в казначейство на получение открытой части электронной цифровой подписи (файлы с расширением. reg). На компьютере, через который осуществляется работа с казначейством через систему СЭД сертификат обычно находится: C:/FKLCNT/SUBSYS/KEYS/CRYPTOAPI/…. В одной из папок с труднопроизносимым названием
· Если не помогают вышеперечисленные способы можно порекомендовать обратиться в казначейство с просьбой сообщить местонахождение сертификата открытого ключа.
3. После подгрузки сертификата открытого ключа в поле «Имя файла сертификата»
появится путь доступа к сертификату. Нажмите кнопку «Далее».
Затем появится окно «Сертификат для установки»
, содержащее информацию об устанавливаемом сертификате. Если все правильно, нажмите кнопку «Далее»
Как посмотреть сертификат
Просмотреть перечень сертификатов, скопировать их, удалить можно с использованием следующих инструментов;
При использовании браузера Internet Explorer выполните следующие действия:
После этого появится окошко, где будет перечислен весь перечень установленных на компьютере открытых сертификатов. Дополнительно будет указан список сторонних поставщиков ПО.
Преимущество использования браузера Internet Explorer — в возможности просмотра списка ключей, даже если нет прав администратора. Недостатком же будет невозможность удаления устаревших или ненужных уже сертификатов с жесткого диска компьютера.
При использовании панели управления OS Windows для просмотра открытых сертификатов, установленных на компьютере, выполните следующие действия с правами администратора:
Для просмотра перечня установленных ранее сертификатов на ПК с помощью приложения «КриптоПРО» достаточно выбрать раздел «Сертификаты». Использование данного ПО позволит при наличии прав администратора не только просматривать, но и копировать открытые сертификаты, удалять их.
В OS Windows есть стандартный менеджер Certmgr для работы с установленными ранее сертификатами. С его помощью можно увидеть информацию об открытых ключах, данные об УЦ. Для использования менеджера выполните следующие действия:
В итоге откроется окно со списком проверочных ключей. Специфика менеджера — в необходимости запуска с правами администратора. Важный минус сервиса — в некорректности отображения ЭЦП, что важно учитывать при просмотре.
Копируем сертификат эцп через «инструменты криптопро»
Этот способ можно использовать на операционных системах Windows и MacOS.
Шаг 1. Откройте приложение «Инструменты КриптоПро» и выберите вкладку «Контейнеры».
Шаг 2. Выберите носитель, на который записан сертификат ЭЦП — то есть, USB-флешку. Нажмите на кнопку «Скопировать контейнер».
Шаг 3. В открывшемся окне выбора нового носителя для сертификата выберите опцию «Реестр» и нажмите «ОК».
Шаг 4. Вернитесь к списку контейнеров. Выберите тот, что скопировали, по считывателю Registry и нажмите на кнопку «Установить сертификат».
Шаг 5. Когда появится уведомление о том, что сертификат успешно установлен, вытащите флешку из разъёма компьютера и проверьте, как работает ваша ЭЦП без токена.
ЭЦП можно установить на рабочий компьютер или ноутбук, и она будет работать без физического носителя. Вы можете сделать это самостоятельно или обратиться за помощью к нашим специалистам.
«Астрал-М» выпускает электронные подписи для физических лиц, индивидуальных предпринимателей и организаций. С нашей подписью можно вести электронный документооборот, участвовать в электронных торгах, сдавать отчётность и работать на государственных порталах. Чтобы приобрести подпись, заполните форму обратной связи, и наш специалист свяжется с вами.
Криптопро csp: как установить сертификат ключа проверки эп в контейнер – подготовка
Первый шаг – это заполнение электронного формуляра данными, необходимыми для формирования запроса на создание СКПЭП. Указать потребуется Ф. И. О. заявителя и действительный адрес его электронной почты.
Для примера рассмотрим, как организована процедура в одном из самых популярных центров сертификации – УЦ Такском. Пользователям предоставляется возможность удаленно получить совершенно новый или проапдейтить имеющийся СКПЭП:
- по карточке (маркеру) временного доступа – если заявитель запрашивает документ впервые;
- по текущему сертификату – на основании уже имеющихся сведений с целью их обновления или при условии, что до окончания периода действия СКПЭП остается меньше двух месяцев и/или требуется коррекция юридического адреса и/или краткого наименования организации.
При заполнении формуляра на сайте УЦ Такском потребуется указать паспортные данные руководителя или уполномоченного сотрудника организации:
- Ф. И. О.;
- пол;
- дату и место рождения;
- гражданство;
- наименование основного документа (паспорт гражданина РФ), его серию, номер, дату выдачи;
- полное наименование выдавшего его госоргана;
- код подразделения.
После завершение ввода данных пользователю нужно нажать желтую кнопку «Продолжить». Он перенаправляется на страницу настройки уведомлений и указывает номер контактного телефона. Спустя несколько секунд приходит СМС-сообщение, содержащее код подтверждения – его нужно ввести в строку новой формы.
Второй шаг – выбор ключевого носителя:
- Криптомодуль откроет новое интерактивное окно в случае, если пользователь подключил к рабочей машине несколько токенов (или смарт-карт). Учтите: при подсоединении всего одного считывателя, последний выбирается программой автоматически – никаких оповещений программа не отсылает.
- Укажите нужное устройство или выделите параметр «Реестр», если хотите с помощью КриптоПро CSP установить сертификат сразу в контейнер хранилища ОС.
- Нажмите «Ok».
- Приложение запустит «Биологический датчик случайных чисел» (далее – БДСЧ) – работа с опцией будет доступна в новом окошке. Следуйте интерактивным подсказкам. БДСЧ генерирует первоначальную последовательность датчика случайных чисел (далее – ДСЧ).
Для успешного завершения процесса нужно нажимать кнопки клавиатуры или перемещать мышку в произвольном порядке.
Криптопро csp: пин код для контейнера: несколько важных замечаний
Первое. При переводе строки в состояние «Установить новый пароль» криптопровайдер защитит доступ к контейнеру паролем, который вы будете вводить с клавиатуры. Если вы установите переключатель на поле «Установить мастер-ключ», приложение закодирует для каталога его текущий ЗК.
Для этого выполните следующие действия:
- Введите название контейнера или выделите его из предложенного программой перечня и нажмите кнопку «Выбрать». На нем будет сохранен новый ЗК в закодированном виде.
- Жмите «Ok».
- Если вы отметите галкой строку «Создать новый контейнер», после совершения этой операции в только что сформированном защищенном каталоге будет сохранен его ЗК в закодированном виде.
Второе. Воспользовавшись опцией «Разделить ключ на несколько носителей», вы сможете защитить каталог, обеспечив доступ к нему только с нескольких устройств одновременно. Каждое из них станет носителем обособленного контейнера с собственным пин-кодом. Заполните формуляр, указав необходимые данные:
- количество загрузочных носителей, необходимых для доступа к формируемому ЗК ключевого контейнера;
- общее число устройств – между ними будут распределены части ключа.
КриптоПро CSP запустит процесс формирования новых контейнеров, участвующих в разделении исходного ключа:
- для каждого формируемого каталога открывается окошко выбора ключевого носителя – укажите нужные;
- по окончании упомянутой операции появится окно ДСЧ;
- сгенерировав числовую последовательность, дождитесь формы ввода пин-кодов к ЗК для каждого созданного контейнера.
По очереди введите их все или выберите другой метод защиты доступа к личным данным, щелкнув кнопку «Подробнее».
Криптопро csp: создаем пароль для контейнера
Третий шаг – ввод пин-кода для контейнера, создаваемого средствами КриптоПро CSP. Сохраните его в надежном месте: если вы его потеряете или забудете, пользоваться СКПЭП станет невозможно. Придется оформлять новый документ.
Примечание. При желании повысить уровень защиты личной информации вызовите опцию «Подробнее». В КриптоПро CSP откроется форма с перечнем способов охраны доступа к закрытому ключу (далее – ЗК) создаваемого контейнера – вы сможете выбрать одно из следующих действий:
- установить новый pin-код;
- задать мастер-ключ (закодировать текущий ЗК и преобразовать его в новый);
- сегментировать пароль и разместить его по частям на нескольких носителях.
В токенах и смарт-картах реализована функция поддержки аппаратного pin-кода – если вы используете одного из подобных устройств для создания нового контейнера, скорее всего, КриптоПро CSP «попросит» ввести пароль, который задается по умолчанию:
- 1234567890 – для eToken/JaCarta;
- 12345678 – для Рутокен/ESMART.
Чтобы защитить создаваемый каталог, укажите в поле «Новый пароль» определенную комбинацию символов, которая известна только вам. Повторите ее в строке «Подтверждение» и кликните «Ok».
Вы можете пропустить этот шаг и не задавать пин-код.
Криптопро вставлен другой носитель: как исправить
Ошибка «Вставьте ключевой носитель» или «Вставлен другой носитель» возникает при попытке подписания электронного документа. Сначала следует убедиться, что USB-токен с сертификатом подключен к ПК (в качестве носителя используются защищенные криптоключи или обычные флешки).
- Открыть меню «Пуск» → «Панель управления» → «КриптоПро CSP».
- Зайти во вкладку «Сервис» → «Посмотреть сертификаты в контейнере» → «Обзор».

- Выбрать из списка ключевой контейнер, нажать ОК и «Далее».
- Нажать «Установить». Если появится предупреждение о том, что сертификат уже присутствует в хранилище, дать согласие на его замену.

- Дождаться загрузки сертификата в хранилище «Личное» и нажать ОК.
После переустановки рекомендуется перезагрузить ПК. Для первичной инсталляции СКПЭП применим аналогичный алгоритм действий.
Недостаточно прав для выполнения операции в криптопро
Ошибка сопровождается уведомлением «У компонента недостаточно прав для доступа к сертификатам». Чаще всего возникает в двух ситуациях:
- При попытке авторизоваться в ЛК, например, на портале контролирующего органа, куда нужно отправить отчет (при нажатии на пиктограмму «Вход по сертификату»).
- При проверке КЭП (при нажатии кнопки «Проверить» в разделе «Помощь»).
Если система уведомила пользователя, что у него недостаточно прав для выполнения операции в КриптоПро, проблема может иметь следующие причины:
- не установлен КриптоПро ЭЦП Browser plug-in 2.0 (или стоит его старая сборка);
- сайт, куда пытается войти клиент, не добавлен в каталог доверенных (надежных) ресурсов.
Browser plug-in — обязательный компонент для применения ЭП на веб-страницах. Он расширяет возможности криптопровайдера, позволяет формировать и проверять электронную подпись на интернет-ресурсах. Без этой программы, КриптоПро не сможет связаться с веб-страницей и реализовать на ней функции КЭП.
- Сохранить дистрибутив cadesplugin.exe.
- Запустить инсталляцию, кликнув по значку установщика.
- Разрешить программе внесение изменений клавишей «Да».
Появится уведомление об успешном результате. Нажмите ОК и перезагрузите браузер, чтобы коррективы вступили в силу.
Для работы с сертификатом ЭП рекомендуется использовать браузер Microsoft Internet Explorer (MIE) — для него не требуются дополнительные настройки. На завершающем этапе необходимо добавить сайт в список доверенных:
- Через меню «Пуск» (CTRL ESC) найти продукт КриптоПро CSP.
- Зайти в настройки плагина ЭЦП Browser.
- В разделе «Список доверенных узлов» ввести адреса всех ресурсов, принимающих ваш сертификат.
Если после перезагрузки ПК проблема не решена, рекомендуется удалить плагин и выполнить повторную инсталляцию.
Удаление веток системного реестра
Довольно эффективным способом устранить дисфункцию, когда не обнаружен контейнер, соответствующий открытому ключу сертификата, является удаление ряда веток системного реестра, ответственных за несовпадение данных.
Выполните следующее:
- Нажмите на клавиши Win R;

- В появившемся окне «Выполнить» введите команду regedit и нажмите ввод;

- В открывшемся окне системного реестра найдите и удалите следующие ветки системного реестра:

Процедура удаления состоит в наведении курсора на данную ветку, клика на правую клавишу мышки, и выбора опции «Удалить».
После удаления обеих веток перезагрузите ваш PC, и попробуйте установить ваш сертификат вновь. Обычно операция проходит без каких-либо проблем.
Читайте также: что предпринять при появлении ошибки генерации сертификата в ЛК налогоплательщика.
Что делать, если система запомнила сервисные пароли и не находит контейнер
Другим способом исправить ситуацию с несоответствующим сертификату контейнером является удаление запомненных системой паролей в «КриптоПро». Для этого перейдите вашу систему «Криптопро», затем выберите «Сервис». Там кликните на опцию «Удалить запомненные пароли», а затем и на «Удалить информацию об используемых съёмных носителях».

Часто выполнение данной операции помогает устранить рассматриваемую нами проблему.
Правильная установка сертификата
Используйте установку сертификата через КриптоПро CSP с переходом в «Сервис», где выберите опцию «Установить личный сертификат».

Проверка сертификата на предмет конфликта со сторонним криптопровайдером
В некоторых случаях в системе может наблюдаться конфликт со сторонним криптопровайдером. Просмотрите список зарегистрированных в вашей системе криптопровайдеров перейдя по приведённым ниже веткам реестра ОС Виндовс.
32-битная операционка:
![]()
64-битная операционка
![]()
Каким образом проверить флеш-накопитель на наличие контейнера
В некоторых случаях контейнер может находиться не используемом нами флеш-накопителей. Скопируйте контейнер в корневой каталог вашей флешки, а затем повторите попытку копирования сертификата.

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

Это также пригодится: «Не удается построить цепочку сертификатов для доверенного корневого центра» — что делать.
Заключение
Выше мы привели перечень способов, позволяющих устранить проблему, сопровождающуюся уведомлением «Не найден контейнер, соответствующий открытому ключу сертификата», а также рассмотрели, что делать в такой ситуации. Наибольшую эффективность показал способ с правкой системного реестра. И мы рекомендуем использовать его для решения возникшей у вас дисфункции.
Читаем закрытый ключ и конвертируем
#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, "x6x7", 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, "x8ax8", 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 %sn", 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 keyn");
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;
}
