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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline FreeZz  
#1 Оставлено : 21 октября 2020 г. 15:40:46(UTC)
FreeZz

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

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

День добрый всем.

Подскажите как все правильно сделать при проверке подписи c помощью phpcades.
Приходят данные в виде JWT-сообщения. Сообщение разделено точками на 3 части. Первая часть содержит информацию об алгоритме шифрования. Вторая часть - не зашифрованные данные. Третья часть - ЭЦП, которая подписывает первые две части, разделенных точкой.

Есть публичный сертификат pub_cert.cer.

Третью часть из base64 я преобразую в бинарный вид размером 64 байта (JWT.input.txt.sgn) и проверяю подпись сообщения (в файле JWT.input.txt) с помощью команды:
Код:
/opt/cprocsp/bin/amd64/csptestf -keys -verify GOST12_256 -in JWT.input.txt -signature JWT.input.txt.sgn -cert pub_cert.cer

Команда успешно отрабатывает, возвращая:
Код:
CSP (Type:80) v4.0.9017 KC2 Release Ver:4.0.9944 OS:Linux CPU:AMD64 FastCode:READY:SSSE3.
AcquireContext: OK. HCRYPTPROV: 28395443
GetProvParam(PP_NAME): Crypto-Pro GOST R 34.10-2012 KC2 CSP
Public key imported from cert file: Tokareva_200914.cer
Hash object created with alg: GOST12_256 0x8021
The data buffer has been hashed.
Signature was verified OK

Total: SYS: 0,000 sec USR: 0,000 sec UTC: 0,020 sec
[ErrorCode: 0x00000000]


Но хочется такую проверку делать не вызывая внешних утилит. Долго копался. Собрал php7.1 с поддержкой openssl + curl + gostengine. Руководствовался статьей https://cyber01.ru/kak-d...-2012-v-centos-redhat-7/

Использую тестовый скрипт.

Код:
<?php

$sign = "ew0KICAiYWxnIjogImdvc3QzNC4xMC0yMDEyIiwNCiAgImtpZCI6ICIxRTRCMTJFQjczN0RBOEQ3MjBFRTNEOTQyQjQwQTQ0MDAzQzAxNkRCIg0KfQ.eyJxcmNJZCI6IkFEMTAwMDJQN0lNNTBENUw5NEw5VjhQU0dKT0lIVVVHIiwidHJ4SWQiOiJBMDI4ODA3MzcwMzk5ODAxMDAwMDA0NDgxODE1RkJB
MSIsImFtb3VudCI6MTAwLCJvcGVyYXRpb25JZCI6Mzc0MTk0MTAsInN0YXR1cyI6ImNvbXBsZXRlZCIsIm9wZXJhdGlvblRpbWVzdGFtcCI6IjIwMjAtMTAtMTRUMDc6Mzc6MDMuNzI5WiJ9.nhycHs6AZpOX7CJCPCPJII5jmxEmWAkKUhYbyPJVtqwkNozGPCtDMsQYjKcvmh0BXfQSr2ZPPNzJnsHkUnVvNQ";

$bs = explode('.', $sign);

$sign_info = $bs[0];
$sign_data = $bs[1];
$sign_sign = $bs[2];

// Конвертированная подпись из base64 в hex
$sign_sign_hex = "9e1c9c1ece80669397ec22423c23c9208e639b112658090a52161bc8f255b6ac24368cc63c2b4332c4188ca72f9a1d015df412af664f3cdcc99ec1e452756f35";
// Разделяем подпись пробелами группами по 2 цифры на байт
$splittedArray = str_split($sign_sign_hex, 2);
$sign_sign_split = implode(" ", $splittedArray);

// Вычисляем хэш сообщения по GOST
$digest = openssl_digest($sign_info . "." . $sign_data, 'GOST R 34.11-2012 with 256 bit hash', false);

$cert = new CPCertificate();
$cert->Import(file_get_contents("./pub_cert.cer"));

$hd = new CPHashedData();
$hd->set_Algorithm(HASH_ALGORITHM_GOSTR_3411);
$hd->SetHashValue($digest);

$rs = new CPRawSignature();
/*
Signature
[in] Значение электронной подписи в виде строки шестнадцатеричных цифр, группами по две цифры на байт, разделённых пробелами.
*/
$r = $rs->VerifyHash($hd, $sign_sign_split, $cert);

print("Result: $r\n");


Завершается ошибкой:

Код:
PHP Fatal error:  Uncaught Exception: Invalid Signature. (0x80090006) in /home/open/www/cert/test_certificate.php:33
Stack trace:
#0 /home/open/www/cert/test_certificate.php(33): CPRawSignature->VerifyHash(Object(CPHashedData), '9e 1c 9c 1e ce ...', Object(CPCertificate))
#1 {main}
  thrown in /home/open/www/cert/test_certificate.php on line 33


Ругается на не правильную подпись. Уже все перепробовал. Что я делаю не так?
Offline Андрей *  
#2 Оставлено : 21 октября 2020 г. 15:44:37(UTC)
Андрей *

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

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

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

HASH_ALGORITHM_GOSTR_3411 - ?
Это 2001 или 2012 ?)
Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей *  
#3 Оставлено : 21 октября 2020 г. 15:46:11(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2034 раз в 1578 постах
Цитата:
// Разделяем подпись пробелами группами по 2 цифры на байт


Зачем?
Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей *  
#4 Оставлено : 21 октября 2020 г. 15:50:17(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2034 раз в 1578 постах
Автор: Андрей * Перейти к цитате
Цитата:
// Разделяем подпись пробелами группами по 2 цифры на байт


Зачем?


понятно, из CPDN взято это описание.
Техническую поддержку оказываем тут
Наша база знаний
Offline FreeZz  
#5 Оставлено : 21 октября 2020 г. 15:55:33(UTC)
FreeZz

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

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

Автор: Андрей * Перейти к цитате
Здравствуйте.

HASH_ALGORITHM_GOSTR_3411 - ?
Это 2001 или 2012 ?)


Смотрел в исходниках, в /opt/cprocsp/src/phpcades/dllmain.cpp. Еще раз внимательно посмотрел. Оказалось, что есть еще одна константа CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256. Сейчас без ошибки отработал.
Offline FreeZz  
#6 Оставлено : 21 октября 2020 г. 16:32:23(UTC)
FreeZz

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

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

Автор: FreeZz Перейти к цитате
Автор: Андрей * Перейти к цитате
Здравствуйте.

HASH_ALGORITHM_GOSTR_3411 - ?
Это 2001 или 2012 ?)


Смотрел в исходниках, в /opt/cprocsp/src/phpcades/dllmain.cpp. Еще раз внимательно посмотрел. Оказалось, что есть еще одна константа CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256. Сейчас без ошибки отработал.


Хм. Отработал без ошибки - это значит все нормально, видимо. В php когда функция null возвращает - это false, как всем известно. Просто в cpdn VerifyHash что-то возвращает. А php, видимо, придется try ... catch использовать. Eh?
Offline FreeZz  
#7 Оставлено : 21 октября 2020 г. 17:05:59(UTC)
FreeZz

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

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

Вот еще вопрос. В этой тестовом скрипте я использую функцию openssl

Код:
$digest = openssl_digest($sign_info . "." . $sign_data, 'GOST R 34.11-2012 with 256 bit hash', false);


А с помощью какого-то объекта и метода phpcades возможно получить такой не подписанный хэш?
Offline FreeZz  
#8 Оставлено : 22 октября 2020 г. 9:43:42(UTC)
FreeZz

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

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

Спасибо всем. Разобрался сам. И еще помогла тема на этом форуме: https://www.cryptopro.ru...aspx?g=posts&t=18326
Offline pz6tnk  
#9 Оставлено : 26 ноября 2020 г. 14:13:54(UTC)
pz6tnk

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

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

Цитата:
Спасибо всем. Разобрался сам. И еще помогла тема на этом форуме: https://www.cryptopro.ru...aspx?g=posts&t=18326


@FreeZz

А не могли бы поделиться кодом, что в итоге получилось
Offline FreeZz  
#10 Оставлено : 8 декабря 2020 г. 9:55:51(UTC)
FreeZz

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

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

Автор: pz6tnk Перейти к цитате
Цитата:
Спасибо всем. Разобрался сам. И еще помогла тема на этом форуме: https://www.cryptopro.ru...aspx?g=posts&t=18326


@FreeZz

А не могли бы поделиться кодом, что в итоге получилось


Да, конечно. Привожу весь код тестового скрипта. Если не возникает исключения в try, то значит подпись была проверена. Сертификат Tokareva_200914.cer это сертификат в формате DER сгенерированный в Крипто Про, видимо, публичный без контейнера закрытого ключа. Его мне выдал банк.
Как понять алгоритм 256 или 512 - я подбирал "методом тыка" через командную строку

Код:

/opt/cprocsp/bin/amd64/csptestf -keys -verify GOST12_256 -in JWT.input.txt -signature JWT.input.txt.sgn -cert Tokareva_200914.cer


JWT.input.txt:
Код:

ew0KICAiYWxnIjogImdvc3QzNC4xMC0yMDEyIiwNCiAgImtpZCI6ICIxRTRCMTJFQjczN0RBOEQ3MjBFRTNEOTQyQjQwQTQ0MDAzQzAxNkRCIg0KfQ.eyJxcmNJZCI6IkFEMTAwMDJQN0lNNTBENUw5NEw5VjhQU0dKT0lIVVVHIiwidHJ4SWQiOiJBMDI4ODA3MzcwMzk5ODAxMDAwMDA0NDgxODE1RkJBMSIsImFtb3VudCI6MTAwLCJvcGVyYXRpb25JZCI6Mzc0MTk0MTAsInN0YXR1cyI6ImNvbXBsZXRlZCIsIm9wZXJhdGlvblRpbWVzdGFtcCI6IjIwMjAtMTAtMTRUMDc6Mzc6MDMuNzI5WiJ9


Тестовый скрипт:

Код:

<?php
$sign = "ew0KICAiYWxnIjogImdvc3QzNC4xMC0yMDEyIiwNCiAgImtpZCI6ICIxRTRCMTJFQjczN0RBOEQ3MjBFRTNEOTQyQjQwQTQ0MDAzQzAxNkRCIg0KfQ.eyJxcmNJZCI6IkFEMTAwMDJQN0lNNTBENUw5NEw5VjhQU0dKT0lIVVVHIiwidHJ4SWQiOiJBMDI4ODA3MzcwMzk5ODAxMDAwMDA0NDgxODE1RkJB
MSIsImFtb3VudCI6MTAwLCJvcGVyYXRpb25JZCI6Mzc0MTk0MTAsInN0YXR1cyI6ImNvbXBsZXRlZCIsIm9wZXJhdGlvblRpbWVzdGFtcCI6IjIwMjAtMTAtMTRUMDc6Mzc6MDMuNzI5WiJ9.nhycHs6AZpOX7CJCPCPJII5jmxEmWAkKUhYbyPJVtqwkNozGPCtDMsQYjKcvmh0BXfQSr2ZPPNzJnsHkUnVvNQ";

$message = "ew0KICAiYWxnIjogImdvc3QzNC4xMC0yMDEyIiwNCiAgImtpZCI6ICIxRTRCMTJFQjczN0RBOEQ3MjBFRTNEOTQyQjQwQTQ0MDAzQzAxNkRCIg0KfQ.eyJxcmNJZCI6IkFEMTAwMDJQN0lNNTBENUw5NEw5VjhQU0dKT0lIVVVHIiwidHJ4SWQiOiJBMDI4ODA3MzcwMzk5ODAxMDAwMDA0NDgxODE1R
kJBMSIsImFtb3VudCI6MTAwLCJvcGVyYXRpb25JZCI6Mzc0MTk0MTAsInN0YXR1cyI6ImNvbXBsZXRlZCIsIm9wZXJhdGlvblRpbWVzdGFtcCI6IjIwMjAtMTAtMTRUMDc6Mzc6MDMuNzI5WiJ9";

$bs = explode('.', $sign);

$sign_info = $bs[0];
$sign_data = $bs[1];
$sign_sign = $bs[2];

$cert = new CPCertificate();
$cert->Import(file_get_contents("./Tokareva_200914.cer"));

// Конвертированная подпись из base64 в hex
$sign_sign_hex = "9e1c9c1ece80669397ec22423c23c9208e639b112658090a52161bc8f255b6ac24368cc63c2b4332c4188ca72f9a1d015df412af664f3cdcc99ec1e452756f35";
// Разделяем подпись пробелами группами по 2 цифры на байт
$splittedArray = str_split($sign_sign_hex, 2);
$sign_sign_split = implode(" ", $splittedArray);

// Вычисляем хэш сообщения по GOST через пересобранный с gostengine opensll 1.1.0h
//$digest = openssl_digest($sign_info . "." . $sign_data, 'GOST R 34.11-2012 with 256 bit hash', false);
//print("OPENSSL Digest: " . $digest . "\n");
//
// Вычисляем хэш полученных не зашифрованных данных с помощью cadesphp
$hd1 = new CPHashedData();
$hd1->set_Algorithm(CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256);
$hd1->set_DataEncoding(BASE64_TO_BINARY);
$hd1->Hash(base64_encode($sign_info . "." . $sign_data));
print("CADES Hash:     " . $hd1->get_Value() . "\n");

$digest = $hd1->get_Value();

$hd = new CPHashedData();
$hd->set_Algorithm(CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256);
$hd->SetHashValue($digest);

$rs = new CPRawSignature();
/*
Signature
[in] Значение электронной подписи в виде строки шестнадцатеричных цифр, группами по две цифры на байт, разделённых пробелами.
*/
try {
    $r = $rs->VerifyHash($hd, $sign_sign_hex, $cert);
} catch(Exception $e) {
    print("Error rised!\n");
    printf($e->getMessage());
}


// 0x80091004   Invalid cryptographic message type      Неправильный формат файла
// 0x80091010   The streamed cryptographic message is not ready to return data  Пустой файл
// 0x80092002   CRYPT_E_BAD_ENCODE - An error occurred during encode or decode operation.
// 0x800B0100   TRUST_E_NOSIGNATURE - No signature was present in the subject.
// 0x80090006   NTE_BAD_SIGNATURE - Invalid Signature.
// 0x8009200B   Не удается найти сертификат и закрытый ключ

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

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