logo Обзор КриптоПро NGate для защищённого доступа к корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

3 Страницы<123
Опции
К последнему сообщению К первому непрочитанному
Offline Shuraken  
#41 Оставлено : 25 декабря 2018 г. 19:52:19(UTC)
Shuraken

Статус: Участник

Группы: Участники
Зарегистрирован: 30.05.2018(UTC)
Сообщений: 18
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Занятно. Удалось выяснить следующую особенность.
При формировании сообщения внутрь него вкладывается публичный сертификат пользователя. После подписания сообщения оно шифруется сертификатом ФСС и отправляется на их сервер. Там сообщение расшифровывается их закрытым ключом, проверяется ЭЦП и формируется ответное сообщение. В него вкладывается публичный сертификат (по идее, тот же самый, которым я шифровал сообщение), подписывается и шифруется.
Если я правильно понял, шифровать они должны моим публичным сертификатом, взятым из подписанного сообщения. Поправьте, если я не прав. И после отправки я расшифровываю его своим закрытым ключом и обрабатываю.
Так вот особенность заключается в том, что я шифрую сообщение сертификатом ФСС с открытым ключом ГОСТ Р 34.10-2001 (512 bit), вкладывая внутрь свой сертификат с открытым ключом, а тестовый сервер, насколько я понял, шифрует ответное сообщение сертификатом ФСС с открытым ключом ГОСТ Р 34.10-2012 256 бит - по крайней мере, в узле <ds:X509Certificate></ds:X509Certificate> содержится именно он.
И когда я пытаюсь расшифровать данные своим сертификатом, он их расшифровать не может и ошибки не выдаёт.
Когда я подменяю сертификаты в сообщении и пытаюсь их расшифровать - ругается на плохие данные.

И как исправить эту ситуацию?
Online two_oceans  
#42 Оставлено : 26 декабря 2018 г. 0:51:41(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 674
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 42 раз
Поблагодарили: 147 раз в 140 постах
Библиотека вообще гост-2012 поддерживает? в приложенном pas файле не заметил упоминаний гост-2012.

Подробно не разбирался с расшифровкой, но навскидку: при варианте через низкоуровневые функции в procedure Tfrm.GetResponseKeysBlobs был приведен код формирования блобов с явными идентификаторами параметров гост-2001(параметры подписи 1.2.643.2.2.36.0 ~ xchgA ~ AT_KEYEXCHANGE, параметры хэширования 1.2.643.2.2.30.1, алгоритм открытого ключа $2e23 ~ 1.2.643.2.2.19), хорошо бы все же выяснить какой алгоритм нужен. Раз уж фигурируют ключи ГОСТ-2012 256 и 512 бит, то очень вероятно что блоб тоже должен содержать параметры гост-2012, а не гост-2001. Это же касается keyParam := CALG_PRO_EXPORT, для гост-2012 есть и другой алгоритм.

Если берется открытый ключ из контекста сертификата, то там есть уже сформированная информация об открытом ключе со всеми нужными идентификаторами самого открытого ключа (причем незашифрованная), ее можно импортировать специальной упрощенной для открытых ключей функцией (в hProv созданный с параметром verifycontext) и получить дескриптор открытого ключа
Код:
pKeyBlob:=@(pCertCont^.pCertInfo^.SubjectPublicKeyInfo);
CryptCheck(CryptImportPublicKeyInfo(hProv,X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,pKeyBlob, hPubKey)
либо можно добавить к ней впереди заголовок блоба (16 байт) и передать в CryptImportKey как у Вас, но тогда опять же надо заголовок заполнить нужными параметрами.

По поводу шифрования вообще - как правило все-таки сертификат адресата для шифрования берется из хранилища, то есть Ваш сертификат должен присутствовать в хранилище сервера. При регистрации в какой-либо информационной системе обычно нужно приложить свой сертификат как раз для добавления в список адресатов. Частным случаем хранилища может выступать файл, но это совершенно не обязательно. Поэтому если при регистрации указывали какой-либо сертификат, то имеет смысл попробовать расшифровать им вместо вложенного при запросе. Насколько помню во всей этой затее с ЭЛН у меня как раз был вопрос откуда ФСС возьмут наш сертификат. Далее у нас в организации решили получать ЭЛН через Контур-Экстерн в ручном режиме, так что вопрос остался незаданным.

Если сертификат вкладывается при подписании, то он может не совпадать с сертификатом шифрования. Например, если на тестовом сервере есть 2 контейнера - 1 для расшифровки (сертификат соответствующий ему от аккредитованного центра Вы используете при зашифровании) и 1 для подписания (сертификат соответствующий ему от тестового центра вкладывается в ответное сообщение и его Вы используете при проверке подписи в тестовом режиме).

Ну и конечно возможна ситуация когда второпях посмотрели на другое поле, так как длина в названии алгортима 256 соответствует размеру открытого ключа 512, длина в названии алгортима 512 - размеру открытого ключа 1024.

Отредактировано пользователем 26 декабря 2018 г. 1:15:01(UTC)  | Причина: Не указана

Offline Shuraken  
#43 Оставлено : 26 декабря 2018 г. 1:46:45(UTC)
Shuraken

Статус: Участник

Группы: Участники
Зарегистрирован: 30.05.2018(UTC)
Сообщений: 18
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Автор: two_oceans Перейти к цитате
Библиотека вообще гост-2012 поддерживает? в приложенном pas файле не заметил упоминаний гост-2012.


Не поддерживает. Когда я пробовал для проверки зашифровать и расшифровать сообщение своим сертификатом с закрытым ключом, то это работало только для сертификата с гост-2001

Автор: two_oceans Перейти к цитате
Подробно не разбирался с расшифровкой, но навскидку при варианте через низкоуровневые функции в procedure Tfrm.GetResponseKeysBlobs был приведен код формирования блобов с явными идентификаторами параметров гост-2001(1.2.643.2.2.36.0 ~ AT_KEYEXCHANGE, 1.2.643.2.2.30.1, $2e23 ~ 1.2.643.2.2.19), хорошо бы все же выяснить какой алгоритм нужен. Раз уж фигурируют ключи ГОСТ-2012 256 и 512 бит, то очень вероятно что блоб тоже должен содержать параметры гост-2012, а не гост-2001. Это же качается keyParam := CALG_PRO_EXPORT, для гост-2012 есть и другой алгоритм.

А как выяснить, какой алгоритм нужен? Я шифрую сообщение сертификатом с гост-2001, в ответ приходит зашифрованное сообщение с публичным сертификатом по гост-2012 256 бит. Вот пример ответа.



Автор: two_oceans Перейти к цитате
По поводу шифрования вообще - как правило все-таки сертификат адресата для шифрования берется из хранилища, то есть Ваш сертификат должен присутствовать в хранилище сервера.

Навряд ли. Если только при получении сообщения они не заносят публичный сертификат из подписи.

Автор: two_oceans Перейти к цитате
Если сертификат вкладывается при подписании, то он может не совпадать с сертификатом шифрования. Например, если на тестовом сервере есть 2 контейнера - 1 для расшифровки (сертификат соответствующий ему от аккредитованного центра Вы используете при зашифровании) и 1 для подписания (сертификат соответствующий ему от тестового центра вкладывается в ответное сообщение и его Вы используете при проверке подписи в тестовом режиме).

Для подписи используются 2 сертификата: по гост-2001, когда сообщение подписывается сертификатом с ключом по этому госту, и сертификат с гост-2012 256 бит, когда сообщение подписывается сертификатом с гост-2012 256 бит. Если же сообщение подписывается сертификатом с гост-2012 512 бит, то в ответном сообщении никакого сертификата не прикладывается.

Шифруется же сообщение всё время одним сертификатом с гост-2012 256 бит.

Честно скажу, из всего вышесказанного не очень понял, как всё-таки расшифровывать их сообщение, имея на руках лишь их открытый сертификат с гост-2001 или гост-2012 256 бит. Можете чуть подробнее осветить этот вопрос?

С уважением, Александр.

Online two_oceans  
#44 Оставлено : 26 декабря 2018 г. 15:16:54(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 674
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 42 раз
Поблагодарили: 147 раз в 140 постах
Как уже я писал подробно в тему ранее не вникал. Поискал по интернету (без обращения к документации самого стандарта xmlenc и добавки для гост), самая полная информация на мой взгляд как раз вот в этой теме в сообщении 17. Частично похоже я был не прав и сертификат берется из сообщения.
По urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001 в примере ответа похоже, что вся схема транспорта ключей на алгоритме гост-2001 (для гост-2012 введены другие идентификаторы) и библиотека по идее должна бы частично работать. Как схема транспорта гост-2001 совмещается с ключом гост-2012 пока мне непонятно, возможно библиотека падает как раз на этом. Или в Вашем контейнере ключ типа AT_SIGNATURE вместо AT_KEYEXCHANGE, тогда большинство высокоуровневых оберток будут спотыкаться на проверке типа ключа, но низкоуровневыми функциями можно использовать и ключ типа AT_SIGNATURE (я так понимаю это потребует замены одного из идентификаторов в блобе). Или ключ из сертификата не соответствует контейнеру.

Сообщение №17 этой темы как раз подробно разжевывает алгоритм шифрования/расшифрования транспорта ключей на алгоритме гост-2001 низкоуровневыми функциями с примерами кода на Дельфи. В частности, еще указываются несколько параметров расшифрования. Следующие 2 сообщения еще и про обработку паддинга вручную уточняют.

Из №14 другой темы узнаем, что п. 4 при отправке запроса как раз сертификат в готовом зашифрованном заменяется на "Ваш" сертификат (для которого у Вас есть контейнер с ключом типа AT_KEYEXCHANGE). Сервер должен зашифровать сообщение, ориентируясь на этот сертификат. Продолжая мысль - при расшифровке ответа нужно проводить операции импорта на экземпляре криптопровайдера связанном с этим же контейнером, на сертификат которого был заменен сертификат в запросе. Соответственно по такой логике сертификат приложенный сервером в ответе приглашает Вас при следующем запросе использовать сертификат из ответа сервера, но сертификат из ответа не участвует в расшифровке. Получается когда используете гост-2001, а сервер предлагает перейти на гост-2012 256. А когда используете гост-2012 512, сервер это устраивает и ничего не предлагает. Ну я понял так.

Определить нужный контейнер можно по-разному.
Какой способ использует библиотека достаточно сложно без декомпиляции/отладки самой библиотеки.

Далее - расшифрованный текст должен представлять собой подписанный сервером xml ответ и в нем уже будет сертификат для проверки подписи ФСС.

Отредактировано пользователем 26 декабря 2018 г. 15:34:28(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
Shuraken оставлено 26.12.2018(UTC)
Offline Shuraken  
#45 Оставлено : 26 декабря 2018 г. 15:55:54(UTC)
Shuraken

Статус: Участник

Группы: Участники
Зарегистрирован: 30.05.2018(UTC)
Сообщений: 18
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
two_oceans, огромное спасибо. Действительно сработало.
Зашифровал их сертификатом при помощи GostEncryptSOAP и заменил их сертификат в зашифрованном сообщении на свой. Получил ответ, заменил их публичный сертификат на свой, и им же расшифровал при помощи GostDecryptSOAP.
Млин, до такого я додуматься не мог.
Offline Shuraken  
#46 Оставлено : 27 декабря 2018 г. 18:29:19(UTC)
Shuraken

Статус: Участник

Группы: Участники
Зарегистрирован: 30.05.2018(UTC)
Сообщений: 18
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Пытаюсь сейчас разобраться с шифрованием и дешифрованием в новых версиях GostCryptography.dll, но в них постоянно вылезают ошибки. Если кто может, проверьте пожалуйста, работают ли у вас функции GostEncryptSoap.encryptMsg и GostDecryptSoap.decryptMsg из аттача. Также прилагаю тестовый проект для проверки. EncryptMessage.rar (9kb) загружен 7 раз(а).

С уважением, Александр.

GostCryptography2020.rar (220kb) загружен 7 раз(а).

Отредактировано пользователем 28 декабря 2018 г. 9:10:28(UTC)  | Причина: Не указана

Offline Shuraken  
#47 Оставлено : 15 января 2019 г. 12:47:42(UTC)
Shuraken

Статус: Участник

Группы: Участники
Зарегистрирован: 30.05.2018(UTC)
Сообщений: 18
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Пытаюсь разобраться с GostCryptography. Скачал версию с гитхаба разработчика: GostCryptography, батником собираю, получаю dll (во вложении). Пытаюсь regasm-ом зарегистрировать - пишет "ни одного типа не найдено". TlbExp создаёт GostCryptography.tlb, но он пустой (также во вложении).
Версия DLL (gostcryptography2020.dll во вложении), поставляемая с АРМ ФСС совпадает по номеру с версией разработчика (2.0.2), но больше на 6Кб и весь необходимый функционал у неё есть, который нормально регистрируется, нормально экспортируется в tlb-файл, нормально переводится в Делфи. Но при попытке шифрования через GostEncryptSOAP выдаёт ошибку: ASN.1 encoded byte array contains invalid structure "GostCryptography.ASN1.PKI.GOSTR34102001.GOSTR34102001PublicKeyParameters". При этом ошибка возникает как при использовании сертификата ФСС с открытым ключом по гост-2001, так и с ключом по гост-2012. Стоит КриптоПро и всё.
Что самое интересное, АРМ ФСС этой ошибки не выдаёт и спокойно загружает тестовые данные как на сертификате по гост-2001, так и по гост-2012.

Если несложно, проверьте пожалуйста, какая длл создаётся у вас при использовании версии с сайта разработчика? В ней также, как и у меня, отсутствуют ссылки на используемый функционал?
И такой вопрос: есть ли у кого-нибудь код шифрования сообщения при помощи gostcryptography.dll, но без использования класса GostEncryptSOAP. Если есть, можете поделиться?

С уважением, Александр.

GostCryptography.rar (141kb) загружен 7 раз(а).
Offline not_x  
#48 Оставлено : 3 апреля 2019 г. 11:23:26(UTC)
not_x

Статус: Участник

Группы: Участники
Зарегистрирован: 27.06.2017(UTC)
Сообщений: 10
Российская Федерация

!

Отредактировано пользователем 3 апреля 2019 г. 12:27:18(UTC)  | Причина: Не указана

Offline not_x  
#49 Оставлено : 3 апреля 2019 г. 11:43:43(UTC)
not_x

Статус: Участник

Группы: Участники
Зарегистрирован: 27.06.2017(UTC)
Сообщений: 10
Российская Федерация

Замечания по раcшифрованию с использованием сертификата ФСС по ГОСТ Р 34.11-2012/34.10-2012 с использованием КриптоПро4:

Согласно документации КриптоПро
https://cpdn.cryptopro.r...784b95e1a4ada0017bf.html
http://cpdn.cryptopro.ru...___pro_c_s_p_ex_DP1.html
http://cpdn.cryptopro.ru...s_i_m_p_l_e_b_l_o_b.html
http://cpdn.cryptopro.ru...l_i_c_k_e_y_b_l_o_b.html

Цитата:

case АлгоритмВСертификате = CALG_GR3411
PublicKeyBlob = { {bType=PUBLICKEYBLOB, bVersion=BLOB_VERSION, 0x00, 0x00, uiKeyAlg = CALG_GR3410EL }, dwMagic = GR3410_1_MAGIC, dwBitLen = 512, bASN1GostR3410_94_PublicKeyParameters = ASN.1(SEQUENCE{ OI=1.2.643.2.2.36.0, OI=1.2.643.2.2.30.1}), bPublicKey = PublicKey}

SessionKeyBlob = { {bType=SIMPLEBLOB, bVersion= BLOB_VERSION, 0x00, 0x00, uiKeyAlg = CALG_G28147}, dwMagic = G28147_MAGIC, uiEncryptKeyAlgId = CALG_G28147, bSV=SessionSV, bEncryptedKey=SessionKey, bMacKey = SessionMAC, bEncryptionParamSet= ANS.1(SEQUENCE{ OI= 1.2.643.2.2.31.1}) }



case АлгоритмВСертификате = CALG_GR3411_2012_256
PublicKeyBlob = { {bType=PUBLICKEYBLOB, bVersion=BLOB_VERSION, 0x00, 0x00, uiKeyAlg = CALG_GR3410_12_256 }, dwMagic = GR3410_1_MAGIC, dwBitLen = 512, bASN1GostR3410_94_PublicKeyParameters = ASN.1(SEQUENCE{ OI=1.2.643.2.2.36.0, OI=1.2.643.7.1.2.5.1.1}), bPublicKey = PublicKey}

SessionKeyBlob = { {bType=SIMPLEBLOB, bVersion= BLOB_VERSION, 0x00, 0x00, uiKeyAlg = CALG_G28147}, dwMagic = G28147_MAGIC, uiEncryptKeyAlgId = CALG_G28147, uiEncryptKeyAlgId = CALG_G28147, bSV=SessionSV, bEncryptedKey=SessionKey, bMacKey = SessionMAC, bEncryptionParamSet= ANS.1(SEQUENCE{ OI= 1.2.643.7.1.2.5.1.1 }) }



case АлгоритмВСертификате = CALG_GR3411_2012_512
PublicKeyBlob = { {bType=PUBLICKEYBLOB, bVersion=BLOB_VERSION, 0x00, 0x00, uiKeyAlg = CALG_GR3410_12_512 }, dwMagic = GR3410_1_MAGIC, dwBitLen = 512, bASN1GostR3410_94_PublicKeyParameters = ASN.1(SEQUENCE{ OI=1.2.643.2.2.36.0, OI=1.2.643.7.1.2.5.1.2}), bPublicKey = PublicKey}

SessionKeyBlob = { {bType=SIMPLEBLOB, bVersion= BLOB_VERSION, 0x00, 0x00, uiKeyAlg = CALG_G28147}, dwMagic = G28147_MAGIC, uiEncryptKeyAlgId = CALG_G28147, uiEncryptKeyAlgId = CALG_G28147, bSV=SessionSV, bEncryptedKey=SessionKey, bMacKey = SessionMAC, bEncryptionParamSet= ANS.1(SEQUENCE{ OI= 1.2.643.7.1.2.5.1.1}) }






При том, что если в PublicKeyBlob вместо CALG_GR3410_12_256,CALG_GR3410_12_512 указать CALG_GR3410EL ошибки при импорте не будет.

Если запрос был зашифрован с использование пользовательского сертификата по ГОСТ Р 34.11-2012/34.10-2012 и сертификатом ФСС ГОСТ Р 34.11/34.10-2001, по ответ будет шифроваться сертификатом ФСС по ГОСТ Р 34.11-2012/34.10-2012

Отредактировано пользователем 3 апреля 2019 г. 12:32:14(UTC)  | Причина: Не указана

Offline not_x  
#50 Оставлено : 3 апреля 2019 г. 11:54:42(UTC)
not_x

Статус: Участник

Группы: Участники
Зарегистрирован: 27.06.2017(UTC)
Сообщений: 10
Российская Федерация

Замечания по шифрованию с использованием сертификата ФСС по ГОСТ Р 34.11-2012/34.10-2012 с использованием КриптоПро4:

Цитата:

case АлгоритмВСертификате = CALG_GR3411
CryptAcquireContextI( ... PROV_GOST_2001_DH ...)

...

// генерация эфемерной ключевой пары

CryptGenKey( ... CALG_DH_EL_EPHEM ...)


case АлгоритмВСертификате = CALG_GR3411_2012_256
CryptAcquireContextI( ... PROV_GOST_2012_256...)

...

// генерация эфемерной ключевой пары

CryptGenKey( ... CALG_DH_GR3410_12_256_EPHEM ...)


case АлгоритмВСертификате = CALG_GR3411_2012_512
CryptAcquireContextI( ... PROV_GOST_2012_512...)

...

// генерация эфемерной ключевой пары

CryptGenKey( ... CALG_DH_GR3410_12_512_EPHEM ...)


Формат "транспортной структуры" ASN.1(GostR3410-KeyTransport) для XML здесь https://www.sql.ru/forum/1280987...ektronnyy-bolnichnyy-eln

или здесь https://www.cryptopro.ru/forum2/....aspx?g=posts&t=8917

Отредактировано пользователем 3 апреля 2019 г. 12:28:26(UTC)  | Причина: Не указана

Offline CryptoGranata  
#51 Оставлено : 10 июля 2019 г. 12:43:12(UTC)
CryptoGranata

Статус: Новичок

Группы: Участники
Зарегистрирован: 30.07.2015(UTC)
Сообщений: 2
Российская Федерация
Откуда: Челябинск

Сказал(а) «Спасибо»: 1 раз
Пробую отправить шифрованное сообщение на 2012 ГОСТе на портал фсс, постоянно возвращается ошибка
"Не удалось расшифровать сообщение. Возможно сообщение зашифровано на ключе отличном от ключа уполномоченного лица ФСС. Проверьте правильность и актуальность ключа уполномоченного лица ФСС"
Открытый ключ вроде как использую валидный, отпечаток ‎15 e1 e8 3f 44 62 fe c8 de 09 04 eb b2 ed 58 4b 99 b9 52 f0

Пример запроса:
Код:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><soapenv:Body wsu:Id="REGNO_7443001611"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sch="http://gost34.ibs.ru/WrapperService/Schema" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><xenc:EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147"/><ds:KeyInfo><xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001"/><ds:KeyInfo><ds:X509Data><ds:X509Certificate>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</ds:X509Certificate></ds:X509Data></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>MIGpMCgEII0vcAJ1ghqaQGermzEuUGBFphzArA2yXw9paW1OxvDKBARCey/soH0GCSqFAwcBAgUBAaBmMB8GCCqFAwcBAQEBMBMGByqFAwICJAAGCCqFAwcBAQICA0MABECQkD3p5agnrJnlp19wkYqeKnrQnrzAir/b3wOWLsQrxGC1C7n1NjHtU3oDIBykb1Oh3ElKRXp8Xu8DClzKFJ0FBAiIKVG09S903g==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>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</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></soapenv:Body></soapenv:Envelope>


Сравнивал структуру ключа со структурой из валидных запросов из примера с форума, всё точно такое же.

Вот пример кода который сейчас у меня применяется, для 2001 ГОСТа всё работает, на 2012 ошибка, может кто увидит в чём ошибка:
Код:

#ifdef LN_GOST_2012
CryptGenKey(hProv, CALG_DH_GR3410_12_256_EPHEM, CRYPT_EXPORTABLE, &hEphemeralKey);
#else
CryptGenKey(hProv, CALG_DH_EL_EPHEM, CRYPT_EXPORTABLE, &hEphemeralKey);
#endif

// Экспорт открытого ключа в BLOB из локального закрытого.
CryptExportKey(hEphemeralKey, 0, PUBLICKEYBLOB, 0, NULL, &pKeyLen);

providerPublicKeyBlob = new unsigned char[pKeyLen];
CryptExportKey(hEphemeralKey, 0, PUBLICKEYBLOB, 0, providerPublicKeyBlob, &pKeyLen);			

// Выделение из BLOB-а контента открытого ключа (структуру BLOB-а см. в GetResponseKeysBlobs),
// который далее пойдет в GostR3410-KeyTransport
publicKey = new unsigned char[pKeyLen];
memcpy(publicKey, providerPublicKeyBlob + pKeyLen - 64, 64);
pKeyLen = 64;

// Получение BLOB открытого ключа удаленного получателя зашифрованного сообщения (ФСС).
// ARemoteCertPath - путь к сертификату открытого ключа удаленного получателя зашифрованного сообщения,
// который, часто, публикуется в открытом доступе, на сайте получателя.
remotePublicKeyBlob = GetRemotePublicKeyBlob(hProv, certPath, remPKeyLen);

// Получение ключа согласования импортом открытого ключа получателя зашифрованного сообщения (ФСС)
// на локальном закрытом ключе отправителя зашифрованного сообщения.
CryptImportKey(hProv, remotePublicKeyBlob, remPKeyLen, hEphemeralKey, 0, &hAgreeKey);

// Установка PRO_EXPORT алгоритма ключа согласования
#ifdef LN_GOST_2012
keyParam = CALG_PRO12_EXPORT;
#else
keyParam = CALG_PRO_EXPORT;
#endif
CryptSetKeyParam(hAgreeKey, KP_ALGID, (PBYTE)&keyParam, 0);

// Создание случайного сессионного ключа, которым будет зашифровано сообщение.
CryptGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hSessionKey)

// Экспорт сессионного ключа в BLOB
CryptExportKey(hSessionKey, hAgreeKey, SIMPLEBLOB, 0, NULL, &size);

sessionKeyBlob = new unsigned char[size];
CryptExportKey(hSessionKey, hAgreeKey, SIMPLEBLOB, 0, sessionKeyBlob, &size));

std::string transportKey = getKeyTransport(sessionKeyBlob, publicKey, pKeyLen);

// Получение из сессионного ключа параметра вектора инициализации. Далее он прикрепляется
// к зашифрованному сообщению (см. ниже)
CryptGetKeyParam(hSessionKey, KP_IV, NULL, &size, 0);
int initVectorSize = size;
initVector = new unsigned char[initVectorSize];
CryptGetKeyParam(hSessionKey, KP_IV, initVector, &size, 0);

// Установка режима шифрования CBC
keyParam = CRYPT_MODE_CBC;
CryptSetKeyParam(hSessionKey, KP_MODE, (PBYTE)&keyParam, 0);

// Определение размера незашифрованного SOAP-запроса.
sourceDataLen = signedXml.length();
encryptDataLen = sourceDataLen;

// Шифрование базового SOAP-запроса
CryptEncrypt(hSessionKey, 0, true, 0, NULL, &encryptDataLen, 0);

encryptedData = new unsigned char[encryptDataLen];
copy(signedXml.begin(), signedXml.end(), encryptedData);
CryptEncrypt(hSessionKey, 0, true, 0, encryptedData, &sourceDataLen, encryptDataLen);

int ciphedLen = encryptDataLen + initVectorSize;
unsigned char *ciphed = new unsigned char[ciphedLen];
memcpy(ciphed, initVector, initVectorSize);
memcpy(ciphed + initVectorSize, encryptedData, encryptDataLen);

std::string encryptedB64 = std_base64::base64_encode(ciphed, ciphedLen);


Функция получени BLOB открытого ключа ФСС:

Код:

unsigned char *GetRemotePublicKeyBlob(HCRYPTPROV ACryptoProvider,
	std::string ARemoteCertPath, unsigned long &keyLen)
{
	PCCERT_CONTEXT certContext = m_fssCerts->GetCurrentCert()->Certificate;
	HCRYPTKEY remotePublicKey;

	// Импорт информации по открытому ключу ФСС
	#ifdef LN_GOST_2012
	CryptImportPublicKeyInfoEx(
			ACryptoProvider,
			X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
			&certContext->pCertInfo->SubjectPublicKeyInfo,
			CALG_GR3410_12_256,
			0,
			NULL,
			&remotePublicKey);
	#else
	CryptImportPublicKeyInfoEx(
		ACryptoProvider,
		X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
		&certContext->pCertInfo->SubjectPublicKeyInfo,
		CALG_GR3410EL,
		0,
		NULL,
		&remotePublicKey);
	#endif

	keyLen = 0;
	CryptExportKey(remotePublicKey, 0, PUBLICKEYBLOB, 0, NULL, &keyLen);
	unsigned char *result = new unsigned char[keyLen];
	CryptExportKey(remotePublicKey, 0, PUBLICKEYBLOB, 0, result, &keyLen);

	if (certContext != NULL)
		CertFreeCertificateContext(certContext);

	if (remotePublicKey != 0)
		CryptDestroyKey(remotePublicKey);

	return result;
}


Код:

std::string getKeyTransport(const BYTE *sessionKeyBlob,
	const BYTE *publicKey, const DWORD &pKeyLen)
{
	const DWORD SESSION_SV_LENGTH = 8;
	const DWORD SESSION_KEY_LENGTH = 32;
	const DWORD SESSION_MAC_LENGTH = 4;

	BYTE *sessionSV = new BYTE[SESSION_SV_LENGTH];
	BYTE *sessionKey = new BYTE[SESSION_KEY_LENGTH];
	BYTE *sessionMAC = new BYTE[SESSION_MAC_LENGTH];

	// Извлечение данных из сессионного ключа.
	memcpy(sessionSV, sessionKeyBlob + 16, 8);
	memcpy(sessionKey, sessionKeyBlob + 24, 32);
	memcpy(sessionMAC, sessionKeyBlob + 56, 4);

//****************************************************************	
	#ifdef LN_GOST_2012
//****************************************************************	
	BYTE keyTransport1[] = { 0x30, 0x81, 0xA9, 0x30, 0x28, 0x04, 0x20 };
	int k1Len = sizeof(keyTransport1);

	BYTE keyTransport2[] = { 0x04, 0x04 };
	int k2Len = sizeof(keyTransport2);

	BYTE keyTransport3[] = { 0xA0, 0x7D, 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02,
 		0x05, 0x01, 0x01, 0xA0, 0x66, 0x30, 0x1F, 0x06, 0x08, 0x2A, 0x85, 0x03,
		0x07, 0x01, 0x01, 0x01, 0x01, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x85, 0x03,
		0x02, 0x02, 0x24, 0x00, 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01,
		0x02, 0x02, 0x03, 0x43, 0x00, 0x04, 0x40 };
	int k3Len = sizeof(keyTransport3);

	BYTE keyTransport4[] = { 0x04, 0x08 };
	int k4Len = sizeof(keyTransport4);
//****************************************************************
	#else
//****************************************************************
	// Подготовка данных для формирования GostR3410-KeyTransport.
	BYTE keyTransport1[] = { 0x30, 0x81, 0xA4, 0x30, 0x28, 0x04, 0x20 };
	int k1Len = sizeof(keyTransport1);

	BYTE keyTransport2[] = { 0x04, 0x04 };
	int k2Len = sizeof(keyTransport2);

	BYTE keyTransport3[] = { 0xA0, 0x78, 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1F,
		0x01, 0xA0, 0x63, 0x30, 0x1C, 0x06, 0x06, 0x2A, 0x85, 0x03, 0x02, 0x02,
		0x13, 0x30, 0x12, 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x24, 0x00,
		0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1E, 0x01, 0x03, 0x43, 0x00,
		0x04, 0x40 };
	int k3Len = sizeof(keyTransport3);

	BYTE keyTransport4[] = { 0x04, 0x08 };
	int k4Len = sizeof(keyTransport4);
//****************************************************************
	#endif
//****************************************************************
	// Формирование структуры GostR3410-KeyTransport.

	BYTE *transportBlob = new BYTE[k1Len + k2Len + k3Len + k4Len +
		SESSION_KEY_LENGTH + SESSION_MAC_LENGTH + pKeyLen + SESSION_SV_LENGTH];
	int back = 0;
	memcpy(transportBlob, keyTransport1, k1Len);
	back += k1Len;
	memcpy(transportBlob + back, sessionKey, SESSION_KEY_LENGTH);
	back += SESSION_KEY_LENGTH;
	memcpy(transportBlob + back, keyTransport2, k2Len);
	back += k2Len;
	memcpy(transportBlob + back, sessionMAC, SESSION_MAC_LENGTH);
	back += SESSION_MAC_LENGTH;
	memcpy(transportBlob + back, keyTransport3, k3Len);
	back += k3Len;
	memcpy(transportBlob + back, publicKey, pKeyLen);
	back += pKeyLen;
	memcpy(transportBlob + back, keyTransport4, k4Len);
	back += k4Len;
	memcpy(transportBlob + back, sessionSV, SESSION_SV_LENGTH);
	back += SESSION_SV_LENGTH;

	std::string result = std_base64::base64_encode(transportBlob, back);

	return result;
}


Возможно есть кто реализовывал запрос, пожалуйста поделитесь примером кода где происходит шифрование.

Отредактировано пользователем 10 июля 2019 г. 13:09:17(UTC)  | Причина: Не указана

Online two_oceans  
#52 Оставлено : 10 июля 2019 г. 13:09:51(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 674
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 42 раз
Поблагодарили: 147 раз в 140 постах
Полагаю после шифрования Вы сразу отправили то, что получилось?

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

Пока в глаза бросилось только то, что Вы ставите схему PRO12 для гост-2012, насколько помню по этому форуму, фсс работает с PRO и для гост-2012 тоже, PRO12 тут лишний.

Отредактировано пользователем 10 июля 2019 г. 13:14:55(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
CryptoGranata оставлено 10.07.2019(UTC)
Offline CryptoGranata  
#53 Оставлено : 10 июля 2019 г. 13:27:28(UTC)
CryptoGranata

Статус: Новичок

Группы: Участники
Зарегистрирован: 30.07.2015(UTC)
Сообщений: 2
Российская Федерация
Откуда: Челябинск

Сказал(а) «Спасибо»: 1 раз
Автор: two_oceans Перейти к цитате
Пока в глаза бросилось только то, что Вы ставите схему PRO12 для гост-2012, насколько помню по этому форуму, фсс работает с PRO и для гост-2012 тоже, PRO12 тут лишний.


Сработало, именно в этом и была ошибка. Спасибо!
Offline PashaTechnique  
#54 Оставлено : 15 августа 2019 г. 8:33:17(UTC)
PashaTechnique

Статус: Активный участник

Группы: Участники
Зарегистрирован: 25.07.2019(UTC)
Сообщений: 31
Российская Федерация

Сказал(а) «Спасибо»: 1 раз
Автор: Shuraken Перейти к цитате
Пытаюсь разобраться с GostCryptography. Скачал версию с гитхаба разработчика: GostCryptography, батником собираю, получаю dll (во вложении). Пытаюсь regasm-ом зарегистрировать - пишет "ни одного типа не найдено". TlbExp создаёт GostCryptography.tlb, но он пустой (также во вложении).
Версия DLL (gostcryptography2020.dll во вложении), поставляемая с АРМ ФСС совпадает по номеру с версией разработчика (2.0.2), но больше на 6Кб и весь необходимый функционал у неё есть, который нормально регистрируется, нормально экспортируется в tlb-файл, нормально переводится в Делфи. Но при попытке шифрования через GostEncryptSOAP выдаёт ошибку: ASN.1 encoded byte array contains invalid structure "GostCryptography.ASN1.PKI.GOSTR34102001.GOSTR34102001PublicKeyParameters". При этом ошибка возникает как при использовании сертификата ФСС с открытым ключом по гост-2001, так и с ключом по гост-2012. Стоит КриптоПро и всё.
Что самое интересное, АРМ ФСС этой ошибки не выдаёт и спокойно загружает тестовые данные как на сертификате по гост-2001, так и по гост-2012.

Если несложно, проверьте пожалуйста, какая длл создаётся у вас при использовании версии с сайта разработчика? В ней также, как и у меня, отсутствуют ссылки на используемый функционал?
И такой вопрос: есть ли у кого-нибудь код шифрования сообщения при помощи gostcryptography.dll, но без использования класса GostEncryptSOAP. Если есть, можете поделиться?

С уважением, Александр.

GostCryptography.rar (141kb) загружен 7 раз(а).


Shuraken, ответь здесь пожалуйста или в лс.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
3 Страницы<123
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.