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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline GennadyTungusov  
#1 Оставлено : 5 августа 2024 г. 16:31:39(UTC)
GennadyTungusov

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

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

Сказал(а) «Спасибо»: 1 раз
Здравствуйте!
Поступила задача по созданию модуля для подписания выбранного файла с помощью ЭЦП в виде отсоединенной подписи.
Посмотрев все, начал делать на C#, глянул примеры, вроде все понятно написано. Делаю, точь-точь как в примерах, но создаю при этом файл и записываю туда результат, чтобы в будущем проверить на сайте: https://dss.cryptopro.ru/verify/#/signature
Или на сайте госуслуг: https://e-trust.gosuslug.../#/portal/sig-check-unep (Отсоединенная ЭП CMS)
Но везде пишет: "Отсутствует подпись под документом" (Госуслуги) или Файл подписи имеет неверный формат. Убедитесь, что данные в файле имеют кодировку Base64 (с/без заголовками) или переданы бинарные данные. Ошибка: [Встречено неверное значение тега ASN1]. Код: [0x8009310b]. (ваш сайт).

Уже который час не могу понять в чем дело, хотя используется токен от рутокена, оттуда данные контейнера указаны верно, если заходить и смотреть через КриптоПро CSP, если проверять через переменные VS, то тоже все подхватывает верно.
Тип криптопровайдера указан верно (в реестре он идет 80). В чем может быть проблема? Где я косячу?

Код на c#:

Код:

static void Main(string[] args)
{
    Console.WriteLine("Начало операции");

    string filename = @"C:\Users\g.rudakov\Desktop\Test 2.pdf";
    SignOfficeDocument(filename);

    Console.WriteLine("Операция завершена!");
}

static void SignOfficeDocument(string path)
{
    CspParameters parameters = new CspParameters(080,
        "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider",
        @"Мак*****_*********************, ГОСТ2012");

    // Объект, реализующий алгоритм вычисления подписи.
    Gost3410_2012_256CryptoServiceProvider Gost = new Gost3410_2012_256CryptoServiceProvider(parameters);
    // Объект, реализующий алгоритм хэширования.
    Gost3411_2012_256CryptoServiceProvider GostHash = new Gost3411_2012_256CryptoServiceProvider();

    byte[] SignedData;
    
    // Открываем для чтения:
    using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
    {
        byte[] data = new byte[fs.Length];
        fs.ReadAsync(data, 0, data.Length);

        SignedData = Gost.SignData(data, GostHash);
        
    }
    string baseString = Convert.ToBase64String(SignedData);
    File.WriteAllText(@"C:\Users\g.rudakov\Desktop\Подпись.pdf.sig", baseString);
}


На выходе получаю файл с следующим содержанием:
Цитата:

aZ4h1oM54aijaCzi7/kTnb0rlxlxdK2WXf8zA7MrK+Z0YXJBzzCTYpqZFbpbwLjxmZdIw5m6a9Q2D23+k2a+og==


Версия КриптоПро CSP 4.0.9963.
Скачано последнее на данный момент SDK
Offline Санчир Момолдаев  
#2 Оставлено : 5 августа 2024 г. 16:36:16(UTC)
Санчир Момолдаев

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

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

Сказал(а) «Спасибо»: 99 раз
Поблагодарили: 271 раз в 252 постах
Добрый день.

вы создали сырую подпись, а не отсоединенную.
вам нужно использовать класс SignedCms
Техническую поддержку оказываем тут
Наша база знаний
Offline GennadyTungusov  
#3 Оставлено : 5 августа 2024 г. 16:53:27(UTC)
GennadyTungusov

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

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

Сказал(а) «Спасибо»: 1 раз
Спасибо, да, мой косяк, подключил, теперь Госуслуги определяют.
Подскажите еще, пожалуйста, в следующем. Теперь мне выдается следующая ошибка от госуслуг:
"Статус подписи: Электронная подпись неверна
Дайджест от контента не совпадает с указанным в подписанных атрибутах"

Не очень понимаю насчет атрибутов. Что-то где-то видел насчет этого, но сразу не понял. Вижу также, что в примерах фигурируют они.
Можете подсказать за что отвечают и как работать вообще с ними?

Повторю уже рабочий код, что госуслуги определяет по подписи, вдруг кто-то наткнется на данный вопрос на форуме и имеет похожую проблему:
Код:

static void Main(string[] args)
{
    Console.WriteLine("Начало операции");

    string filename = @"C:\Users\g.rudakov\Desktop\Test 2.pdf";
    SignOfficeDocument(filename);

    Console.WriteLine("Операция завершена!");
}

static void SignOfficeDocument(string path)
{
    CspParameters parameters = new CspParameters(080,
        "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider",
        @"Ма****************************, ГОСТ2012");

    // Объект, реализующий алгоритм вычисления подписи.
    Gost3410_2012_256CryptoServiceProvider Gost = new Gost3410_2012_256CryptoServiceProvider(parameters);
    // Объект, реализующий алгритм хэширования.
    Gost3411_2012_256CryptoServiceProvider GostHash = new Gost3411_2012_256CryptoServiceProvider();

    X509Certificate2 certificate = Gost.ContainerCertificate;
    AsymmetricAlgorithm key = certificate.PrivateKey;


    byte[] SignedData;
    
    // Открываем для чтения:
    using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
    {
        byte[] data = new byte[fs.Length];
        fs.ReadAsync(data, 0, data.Length);

        SignedData = Gost.SignData(data, GostHash);
        
    }

    byte[] signature;
    using (var gostCert = certificate)
    {
        var contentInfo = new ContentInfo(SignedData);
        var signedCms = new SignedCms(contentInfo, false);
        CmsSigner cmsSigner = new CmsSigner(gostCert);
        signedCms.ComputeSignature(cmsSigner);
        signature = signedCms.Encode();
        Console.WriteLine($"CMS Sign: {Convert.ToBase64String(signature)}");
    }

    string baseString = Convert.ToBase64String(signature);
    File.WriteAllText(@"C:\Users\g.rudakov\Desktop\Подпись.pdf.sig", baseString);
}
Offline Санчир Момолдаев  
#4 Оставлено : 5 августа 2024 г. 20:59:45(UTC)
Санчир Момолдаев

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

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

Сказал(а) «Спасибо»: 99 раз
Поблагодарили: 271 раз в 252 постах
сюда
new ContentInfo(SignedData);
нужно передать непосредственно данные которые вы хотите подписывать.
весь код про сырую подпись можно удалить
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Санчир Момолдаев за этот пост.
Андрей * оставлено 06.08.2024(UTC)
Offline GennadyTungusov  
#5 Оставлено : 6 августа 2024 г. 8:34:12(UTC)
GennadyTungusov

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

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

Сказал(а) «Спасибо»: 1 раз
Большое спасибо, вес исправил, все заработало!

Итоговый рабочий код, если кто наткнется на подобную задачу*
Код:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using CryptoPro.Sharpei;


namespace CryptoProModule
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Начало операции");

            string filename = @"C:\Users\g.rudakov\Desktop\Test 2.pdf";
            SignOfficeDocument(filename);

            Console.WriteLine("Операция завершена!");
        }

        static void SignOfficeDocument(string path)
        {
            CspParameters parameters = new CspParameters(80,
                "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider",
                @"Макси******************");

            // Объект, реализующий алгоритм вычисления подписи.
            Gost3410_2012_256CryptoServiceProvider Gost = new Gost3410_2012_256CryptoServiceProvider(parameters);

            byte[] signature;

            // Открываем для чтения:
            using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                byte[] data = new byte[fs.Length];
                fs.ReadAsync(data, 0, data.Length);

                using (var gostCert = Gost.ContainerCertificate)
                {
                    var contentInfo = new ContentInfo(data);
                    var signedCms = new SignedCms(contentInfo, true);
                    CmsSigner cmsSigner = new CmsSigner(gostCert);
                    signedCms.ComputeSignature(cmsSigner);
                    signature = signedCms.Encode();
                    Console.WriteLine($"CMS Sign: {Convert.ToBase64String(signature)}");
                }
                
            }

            string baseString = Convert.ToBase64String(signature);
            File.WriteAllText(@"C:\Users\g.rudakov\Desktop\Подпись.pdf.sig", baseString);
        }
    }
}

Offline Андрей *  
#6 Оставлено : 6 августа 2024 г. 10:52:57(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2201 раз в 1717 постах
еще есть File.ReadAllBytes... чтобы упростить
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
GennadyTungusov оставлено 06.08.2024(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.