Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

3 Страницы<123>
Опции
К последнему сообщению К первому непрочитанному
Offline Александр Лавник  
#11 Оставлено : 13 июля 2020 г. 16:43:09(UTC)
Александр Лавник

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 30.06.2016(UTC)
Сообщений: 3,376
Мужчина
Российская Федерация

Сказал «Спасибо»: 53 раз
Поблагодарили: 773 раз в 715 постах
Здравствуйте.

Похоже, что реализация корректна.

Вам необходимо еще учесть, что полученную сырую подпись необходимо побайтово перевернуть:

Цитата:
При использовании API КриптоПро, для формирования хеша используется функция CryptHashData,
после формирования подписи функцией CryptSignHash, полученный набор байт следует
инвертировать перед кодированием в base64. Т.е. в base64 кодируется массив байт "задом-наперед"
от полученного функцией CryptSignHash.
Техническую поддержку оказываем тут
Наша база знаний
Offline Александр Лавник  
#12 Оставлено : 13 июля 2020 г. 21:14:13(UTC)
Александр Лавник

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 30.06.2016(UTC)
Сообщений: 3,376
Мужчина
Российская Федерация

Сказал «Спасибо»: 53 раз
Поблагодарили: 773 раз в 715 постах
Всё-таки необходимо кое-что изменить в Вашем коде:

Код:
$hd->Hash($content);

нужно заменить на:

Код:
$hd->set_DataEncoding(BASE64_TO_BINARY);
$hd->hash(base64_encode($content));
Техническую поддержку оказываем тут
Наша база знаний
Offline eisy  
#13 Оставлено : 23 июля 2020 г. 13:14:51(UTC)
eisy

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

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

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 1 раз в 1 постах
Автор: Александр Лавник Перейти к цитате
Всё-таки необходимо кое-что изменить в Вашем коде:

Код:
$hd->Hash($content);

нужно заменить на:

Код:
$hd->set_DataEncoding(BASE64_TO_BINARY);
$hd->hash(base64_encode($content));


В общем ждал пока получу нужные контейнеры, до этого все с тестовым сертификатом пробовал.

Код и так и так пробовал, сырую подпись инвертировал, но взаимодействовать с нужным мне сервисом не удалось :(
Даже не знаю что ещё бы попробовать

Цитата:
{"Error":"Проверка ЭЦП завершилась с результатом 80090006: Invalid Signature.. Signarure представляет собой подписанный хэш данных, кодированный в base64.Расчёт хеш-суммы, 256 бит - ГОСТ Р 34.11-2012. Расчет подписи, 256 бит - ГОСТ Р 34.10-2012. Подпись передается без контейнера. Подписываемая последовательность представляет собой конкатенацию части Header и Payload разделенных символом точка. Разделитель \".\" входит в последовательность. Для JWT отправляемых в метод \"/api/token/info\" \"Header..signature\" \".\" входит в последовательность пример : \"Header.\" . Также, следуют учитывать особенность работы ГОСТ алгоритмов: При использовании API КриптоПро, для формирования хеша используется функция CryptHashData, после формирования подписи функцией CryptSignHash, полученный набор байт следует инвертировать перед кодированием в base64. Т.е. в base64 кодируется массив байт \"задом-наперед\" от полученного функцией CryptSignHash.","ErrorCode":5001}

Отредактировано пользователем 23 июля 2020 г. 13:15:30(UTC)  | Причина: Не указана

Offline Александр Лавник  
#14 Оставлено : 23 июля 2020 г. 13:29:23(UTC)
Александр Лавник

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 30.06.2016(UTC)
Сообщений: 3,376
Мужчина
Российская Федерация

Сказал «Спасибо»: 53 раз
Поблагодарили: 773 раз в 715 постах
Автор: eisy Перейти к цитате
Автор: Александр Лавник Перейти к цитате
Всё-таки необходимо кое-что изменить в Вашем коде:

Код:
$hd->Hash($content);

нужно заменить на:

Код:
$hd->set_DataEncoding(BASE64_TO_BINARY);
$hd->hash(base64_encode($content));


В общем ждал пока получу нужные контейнеры, до этого все с тестовым сертификатом пробовал.

Код и так и так пробовал, сырую подпись инвертировал, но взаимодействовать с нужным мне сервисом не удалось :(
Даже не знаю что ещё бы попробовать

Цитата:
{"Error":"Проверка ЭЦП завершилась с результатом 80090006: Invalid Signature.. Signarure представляет собой подписанный хэш данных, кодированный в base64.Расчёт хеш-суммы, 256 бит - ГОСТ Р 34.11-2012. Расчет подписи, 256 бит - ГОСТ Р 34.10-2012. Подпись передается без контейнера. Подписываемая последовательность представляет собой конкатенацию части Header и Payload разделенных символом точка. Разделитель \".\" входит в последовательность. Для JWT отправляемых в метод \"/api/token/info\" \"Header..signature\" \".\" входит в последовательность пример : \"Header.\" . Также, следуют учитывать особенность работы ГОСТ алгоритмов: При использовании API КриптоПро, для формирования хеша используется функция CryptHashData, после формирования подписи функцией CryptSignHash, полученный набор байт следует инвертировать перед кодированием в base64. Т.е. в base64 кодируется массив байт \"задом-наперед\" от полученного функцией CryptSignHash.","ErrorCode":5001}

Здравствуйте.

Raw подпись инвертировали побайтово перед преобразованием в Base64?

Где можно ознакомится с требованиями к нужной Вам подписи?
Техническую поддержку оказываем тут
Наша база знаний
Offline eisy  
#15 Оставлено : 23 июля 2020 г. 15:51:44(UTC)
eisy

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

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

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 1 раз в 1 постах
Автор: Александр Лавник Перейти к цитате
Автор: eisy Перейти к цитате
Автор: Александр Лавник Перейти к цитате
Всё-таки необходимо кое-что изменить в Вашем коде:

Код:
$hd->Hash($content);

нужно заменить на:

Код:
$hd->set_DataEncoding(BASE64_TO_BINARY);
$hd->hash(base64_encode($content));


В общем ждал пока получу нужные контейнеры, до этого все с тестовым сертификатом пробовал.

Код и так и так пробовал, сырую подпись инвертировал, но взаимодействовать с нужным мне сервисом не удалось :(
Даже не знаю что ещё бы попробовать

Цитата:
{"Error":"Проверка ЭЦП завершилась с результатом 80090006: Invalid Signature.. Signarure представляет собой подписанный хэш данных, кодированный в base64.Расчёт хеш-суммы, 256 бит - ГОСТ Р 34.11-2012. Расчет подписи, 256 бит - ГОСТ Р 34.10-2012. Подпись передается без контейнера. Подписываемая последовательность представляет собой конкатенацию части Header и Payload разделенных символом точка. Разделитель \".\" входит в последовательность. Для JWT отправляемых в метод \"/api/token/info\" \"Header..signature\" \".\" входит в последовательность пример : \"Header.\" . Также, следуют учитывать особенность работы ГОСТ алгоритмов: При использовании API КриптоПро, для формирования хеша используется функция CryptHashData, после формирования подписи функцией CryptSignHash, полученный набор байт следует инвертировать перед кодированием в base64. Т.е. в base64 кодируется массив байт \"задом-наперед\" от полученного функцией CryptSignHash.","ErrorCode":5001}

Здравствуйте.

Raw подпись инвертировали побайтово перед преобразованием в Base64?

Где можно ознакомится с требованиями к нужной Вам подписи?



Да подпись инвертировал, спецификация суперсервиса вот, 4-6 страницы
Specifikacija servisa vzaimodejjstvija (API) v_2_1 (1) 18 ijunja 2020.docx (184kb) загружен 12 раз(а).

Цитата:
Verify signarure
Verify signarure представляет закодированную в Base64 ЭЦП по ГОСТ 34.10-2012 см. выше соответствующий цвет. Подписываемая последовательность представляет собой конкатенацию части Header и Payload разделенных символом точка.
Открытый ключ сертификата, которым осуществляется подпись помещается в виде x509 сертификата закодированного в Base64 в Header в поле cert64.


Ошибка именно с сигнатурой, сертификат в x509 гружу, структура запроса тоже корректная, по ней ошибок нет

Отредактировано пользователем 23 июля 2020 г. 15:53:22(UTC)  | Причина: Не указана

Offline eisy  
#16 Оставлено : 31 июля 2020 г. 11:03:49(UTC)
eisy

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

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

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 1 раз в 1 постах
Пообщался с тех поддержкой, они говорят вот чего.

Цитата:
По представленным кускам кода , предполагается, что в используемой обертке
над CriptoPRO , вызывается функция, производящая операцию, отличную от
требуемой.


Скинули пример, у них подпись такая получается
Цитата:
_I\F3Aq Gn!3լAIwpg x{]rhމr6gb#

У меня, по процедурам выше явно другой формат
Цитата:
FC3054F94299653582DFA04F998E8C06FCD5A929CA5B64861A5528C4A84AC97AA8C1911641EDF7D2195B435727C97015AA56AEEEF06B9E92C79FDDBAB09918E5


Ещё скинули файл на Си, но я его не особо знаю, как и функции в библиотеке крипто про, чтоб понять как сделать аналогично


Цитата:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>

#include <WinCryptEx.h>

#define GR3411LEN 64

#define LANGUAGE 1033

char* Signature(BYTE* bdata, DWORD lenData) {
char* result = NULL;

BYTE* sigData = NULL;
BYTE * tempSig = NULL;
PCCERT_CONTEXT pCertCtx = NULL;
HCERTSTORE hCertStore = NULL;
CERT_PUBLIC_KEY_INFO* pubKeyInfo = NULL;


HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;

if(!CryptAcquireContext(
&hProv,
"\\\\.\\HDIMAGE\\test",
NULL,
PROV_GOST_2012_256,
CRYPT_SILENT)) {
goto Finish;
}

DWORD kiLen = 0;
if(CryptExportPublicKeyInfo(hProv,AT_KEYEXCHANGE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, &kiLen))
{
pubKeyInfo = (CERT_PUBLIC_KEY_INFO*)malloc(kiLen);
if(!CryptExportPublicKeyInfo(hProv,AT_KEYEXCHANGE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pubKeyInfo, &kiLen)) {
goto Finish;
}
}
else {
goto Finish;
}

if(pubKeyInfo == NULL) {
goto Finish;
}

if(!CryptCreateHash(hProv, CALG_GR3411_2012_256, 0, 0, &hHash)) {
goto Finish;
}

if(!CryptHashData(hHash, bdata, lenData, 0)) {
goto Finish;
}

DWORD sigLen = 0;
if(!CryptSignHash(
hHash,
AT_KEYEXCHANGE,
NULL,
0,
NULL,
&sigLen)) {
goto Finish;
}

sigData = (BYTE*)malloc(sigLen*sizeof(BYTE));
if(!CryptSignHash(
hHash,
AT_KEYEXCHANGE,
NULL,
0,
sigData,
&sigLen)) {
goto Finish;
}

tempSig = (BYTE*) malloc(sigLen);
DWORD j;
for(j = 0; j < sigLen; j++)
{
tempSig[j] = sigData[sigLen - j - 1];
}

DWORD nLenOut=0;
char* tmpString = NULL;
if(CryptBinaryToString(
tempSig, sigLen,
CRYPT_STRING_BASE64,
NULL, &nLenOut)
) {
tmpString = (char*)malloc(nLenOut*sizeof(char));
if(!CryptBinaryToString(tempSig, sigLen, CRYPT_STRING_BASE64, tmpString, &nLenOut)) {
goto Finish;
}
}
else {
goto Finish;
}

result = tmpString;

Finish:
if(hHash) CryptDestroyHash(hHash);
if(hProv) CryptReleaseContext(hProv, 0);
if(tempSig) free(tempSig);
if(bdata) free(bdata);
if(sigData) free(sigData);


hHash = 0;
hProv = 0;

return result;
}

char* Verify(BYTE* bData, DWORD dataLen,BYTE* bcert, DWORD lenCert, BYTE* bSign, DWORD signLen){
char* result = NULL;

BYTE* tempSig = NULL;
PCCERT_CONTEXT ppCertCtx = NULL;

HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
if(!CryptAcquireContext(
&hProv,
NULL,
NULL,
PROV_GOST_2012_256,
CRYPT_VERIFYCONTEXT))
{
goto Finish;
}

if(!CryptCreateHash(hProv, CALG_GR3411_2012_256, 0, 0, &hHash))
{
CryptReleaseContext(hProv, 0);
goto Finish;
}

ppCertCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bcert,lenCert);
if (ppCertCtx == NULL) {
goto Finish;
}

HCRYPTKEY hPubKey = 0;
CERT_PUBLIC_KEY_INFO kInf = ppCertCtx->pCertInfo->SubjectPublicKeyInfo;
if(!CryptImportPublicKeyInfo(hProv, (DWORD) ppCertCtx->dwCertEncodingType, &kInf, &hPubKey)) {
goto Finish;
}

tempSig = (BYTE*) malloc(signLen);
DWORD j;
for(j = 0; j < signLen; j++)
{
tempSig[j] = bSign[signLen - j - 1];
}

if(!CryptHashData(hHash, bData, dataLen, 0))
{
goto Finish;
}

if(CryptVerifySignature(hHash,tempSig,signLen,hPubKey,NULL, 0))
{
result = "true";
}
else
{
result = "false";
}

Finish:
if(tempSig) free(tempSig);
if(bData) free(bData);
if(bSign) free(bSign);

if(hProv) CryptReleaseContext(hProv, 0);
if(hHash) CryptDestroyHash(hHash);
if(ppCertCtx) CertFreeCertificateContext(ppCertCtx);

return result;
}

int
main(const int argc, const char **argv) {
return 1;
}

Отредактировано пользователем 31 июля 2020 г. 11:05:03(UTC)  | Причина: Не указана

Offline eisy  
#17 Оставлено : 4 августа 2020 г. 21:29:01(UTC)
eisy

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

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

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 1 раз в 1 постах
Автор: Александр Лавник Перейти к цитате
Всё-таки необходимо кое-что изменить в Вашем коде:

Код:
$hd->Hash($content);

нужно заменить на:

Код:
$hd->set_DataEncoding(BASE64_TO_BINARY);
$hd->hash(base64_encode($content));


Может быть подскажете для чего это? может быть мелочь как раз в этом моменте кроется? учитывая что у меня на подпись передаются данные в ввиде "base64.base64"
Offline Андрей *  
#18 Оставлено : 4 августа 2020 г. 22:29:44(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,630
Мужчина
Российская Федерация

Сказал «Спасибо»: 494 раз
Поблагодарили: 2034 раз в 1578 постах
Автор: eisy Перейти к цитате
Автор: Александр Лавник Перейти к цитате
Всё-таки необходимо кое-что изменить в Вашем коде:

Код:
$hd->Hash($content);

нужно заменить на:

Код:
$hd->set_DataEncoding(BASE64_TO_BINARY);
$hd->hash(base64_encode($content));


Может быть подскажете для чего это? может быть мелочь как раз в этом моменте кроется? учитывая что у меня на подпись передаются данные в ввиде "base64.base64"


Особенности работы с подписываемыми данными
base64 - служит для передачи данных внутрь функции, где они раскодируются в исходные (указание BASE64_TO_BINARY).
Техническую поддержку оказываем тут
Наша база знаний
Offline AlvarCrash  
#19 Оставлено : 22 марта 2021 г. 23:40:26(UTC)
AlvarCrash

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

Группы: Участники
Зарегистрирован: 22.03.2021(UTC)
Сообщений: 28

Сказал(а) «Спасибо»: 3 раз
Прошу прощения, что вклиниваюсь, но столкнулся с такой же проблемой, как и у топикстартера.

Единственно, что я импортировал сертификат и закрытый ключ из pfx файла. В итоге контейнер ЗК создался, сертификат в uMy присутствует, но при выполнении кода:

<?php
$store = new CPStore();
$store->Open(CURRENT_USER_STORE, "My", STORE_OPEN_READ_ONLY);

$certs = $store->get_Certificates();
var_dump($certs);
?>

Имею точно такую же ошибку, как и в первом посте.

Подскажите, пожалуйста, куда копать? Спасибо!
Offline two_oceans  
#20 Оставлено : 24 марта 2021 г. 6:45:09(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 393 раз в 366 постах
Добрый день.
Наводящие вопросы:
1. Операционная система и разрядность?
2. Контейнер на носителе какого типа (Флешка / Реестр / Несистемный диск / Директория)?
3. Пользователь под которым видите сертификат в uMy совпадает с пользователем под которым выполняется PHP?

Вкратце: на любой ос есть разница между установкой в хранилище пользователя и в хранилище компьютера. На windows Реестр и Директория (в случае *nix - Директория) видны только тому же пользователю.

Обратите внимание, что если что-то видно под sudo - это тоже будет означать другого пользователя (команда фактически выполняется не под текущим пользователем, а под root). Поэтому для установки в uMy и его просмотра не рекомендуется использовать sudo. Другое дело mRoot - там sudo или вход как root нужны.

В случае службы / демона PHP также может запускаться под иным пользователем. Еще вариант - разрядность приложения (то есть библиотек php или CGI интерперетатора php) желательно чтобы совпадала с разрядностью операционной системы.

Ну и в конце концов обратите внимание на флаг STORE_OPEN_READ_ONLY. По моему личному мнению (но доказательств пока так и не нашел) этот правильный по логике флаг иногда становится причиной некорректного открытия хранилища. На uMy по идее у пользователя есть все права, можно не ограничиваться "только чтением".
thanks 1 пользователь поблагодарил two_oceans за этот пост.
AlvarCrash оставлено 24.03.2021(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
3 Страницы<123>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.