Closed elvirazakharova closed 4 years ago
Присоединяюсь к вопросу, у нас аналогичная проблема:
@elvirazakharova Что вы и как пытаетесь подписать? У вас есть бинарное представление подписи?
@ethaniel Операция подписания происходит на клиентской стороне, поэтому нам в PostMessagePatch не нужно передавать сертификат, нужно передавать подпись.
@atytsky у нас есть "-----BEGIN CERTIFICATE-----" и "-----BEGIN ENCRYPTED PRIVATE KEY-----". Я так понимаю, что сам PRIVATE KEY мы передавать не должны. Как должна выглядеть подпись?
@ethaniel конечно нет, Private Key — это ваш секрет, он как раз нужен для подписания/шифрования различного контента. Про подписи можно почитать например тут, или вот еще хорошая спека
Вообще, уже есть сертифицированные криптопровайдеры, которые умеют делать хорошие подписи, самый популярный — Крипто ПРо
@ethaniel конечно нет, Private Key — это ваш секрет, он как раз нужен для подписания/шифрования различного контента. Про подписи можно почитать например тут, или вот еще хорошая спека
Да вот только непонятно, что именно мы подписываем. Нужно заново скачать обратно XML по 820 приказу через GetMessage и заново его подписать как в SignedContent? Мы делаем все на PHP и JSON к примеру, поэтому нехватка документации и примеров смущает.
Весь workflow описан здесь. Вам надо подписать XML-файл 1-го, либо 2-го титула (в зависимости от того, получаете или отправляете документ).
Если вы отправляете — подписывается 1-й титул УПД по №820, если получаете 2-й титул.
Частично разобралась. Надеюсь это поможет многим людям за неимением какого-либо мануала в доступе. Для подписания титула (PostMessagePatch) покупателем понадобятся:
@elvirazakharova в целом описано все верно, но есть следующие моменты:
Если кому-то нужно пример на php (linux), то вот наша функция для подписания документов:
function diadoc_sign($data) {
$descriptorspec = array(0 => array("pipe", "r"),1 => array("pipe", "w"),2 => array("pipe", "w"));
$q = "/usr/local/openssl-gost/bin/openssl smime -sign -binary -noattr -gost89 -outform der -signer ".DIADOC_KEY." -inkey ".DIADOC_KEY." -passin pass:".DIADOC_KEYPASS;
$process = proc_open($q, $descriptorspec, $pipes);
$token = "";
if (is_resource($process)) {
fwrite($pipes[0], $data);
fclose($pipes[0]);
$content = stream_get_contents($pipes[1]);
$err = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$resCode = proc_close($process);
if ($resCode != 0) {
echo "Сбой на сервере. Пожалуйста, попробуйте позднее [1: $err].";
return false;
} else {
//echo $content;
//$content = join("\n",array_slice(array_filter(explode("\n",$content)),1,-1));
}
} else {
echo "Сбой на сервере. Пожалуйста, попробуйте позднее [2].";
return false;
}
return $content;
}
DIADOC_KEY - константа с местоположением PEM файла с ключом и сертификатом
DIADOC_KEYPASS - константа с паролем от ключа
/usr/local/openssl-gost/bin/openssl - наш локально собранный openssl с поддержкой ГОСТ-2012 (использовали вот эти примеры - https://github.com/kov-serg/get-cpcert)
Экспортировали ключ и сертификат из КриптоПро при помощи лицензионной P12FromGostCSP (только она может экспортировать ключи ГОСТ-2012 в PFX файлы, http://soft.lissi.ru/ls_product/utils/p12fromcsp/)
Конвертировали PFX в PEM при помощи /usr/local/openssl-gost/bin/openssl pkcs12 -passin pass: -in p12.pfx -clcerts -outfile certkey.pem
(она же и предлагает указать пароль для ключа при его сохранении в PEM)
Как с помощью КриптоПро выгрузить подпись для методов PostMessagePatch и GenerateUniversalTransferDocumentXmlForBuyer . Подпись в формате X509 Base64 не подходит для метода PostMessagePatch, ошибка "Invalid signature". Файл подписи в формате PKCS7 (.p7b) кодированный в Base64 дает ошибку "The server encountered an internal error or misconfiguration and was unable to complete your request"