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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline Leonra_NzOe075n  
#1 Оставлено : 1 декабря 2023 г. 12:53:19(UTC)
Leonra_NzOe075n

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

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

Сказал(а) «Спасибо»: 1 раз
Добрый день, уважаемые форумчане!
Помогите, пожалуйста, разобраться.

Задача: требуется "подпись запроса в формате PKCS#7 detached signature в формате urlSafeBase64 в кодировке UTF-8 – подписанный не ранее, чем за 24 часа (86400 с) параметр UUID сертификатом организации, на сотрудника которой был выдан (сформирован) идентификационный ключ".

Я установила КриптоПро .NET и КриптоПро .NET SDK. Нашла примеры - .NET SDK\Examples\simple.zip\CMS\cs\DetachedSignature.cs
Полностью взяла код из этого файла, но у меня ничего не работает.

Код:

public static byte[] MainMethod(string[] args, String msg)
{
    try
    {
        ClearLog();

        // Проверка корректности переданных параметров.
        if (args.Length < 1)
        {
            Log(string.Format("CMS.DetachedSignature <cert-subject>"));
            return Array.Empty<byte>();
        }

        String signerName = args[0];

        // Исходное сообщение.
        //const String msg = "Это сообщение, которое будет подписано.";

        Log(string.Format("{0}Исходное сообщение (длина {1}): {2}  ",
            Environment.NewLine, msg.Length, msg));

        // Переводим исходное сообщение в массив байтов.
        Encoding unicode = Encoding.UTF8;
        byte[] msgBytes = unicode.GetBytes(msg);

        Log(string.Format("{0}{0}------------------------------",
            Environment.NewLine));
        Log(string.Format(" Поиск сертификата            "));
        Log(string.Format("------------------------------{0}",
            Environment.NewLine));

        // Получаем сертификат ключа подписи;
        // он будет использоваться для получения 
        // секретного ключа подписи.
        X509Certificate2 signerCert = GetSignerCert(signerName);

        Log(string.Format("{0}{0}------------------------------",
            Environment.NewLine));
        Log(string.Format(" На стороне отправителя"));
        Log(string.Format("------------------------------{0}",
            Environment.NewLine));

        byte[] encodedSignature = SignMsg(msgBytes, signerCert);
        File.WriteAllBytes("signature.bin", encodedSignature);

        Log(string.Format("{0}{0}------------------------------",
            Environment.NewLine));
        Log(string.Format(" На стороне получателя  "));
        Log(string.Format("------------------------------{0}",
            Environment.NewLine));

        // При проверка detached подписи передаем и само сообщение
        if (VerifyMsg(msgBytes, encodedSignature))
        {
            Log(string.Format("{0}Сообщение проверено.",
                Environment.NewLine));
        }
        else
        {
            Log(string.Format("{0}Ошибка при проверке сообщения.",
                Environment.NewLine));
        }

        return encodedSignature;
    }
    catch (Exception)
    {
        return new byte[0];
    }
}

// Открываем хранилище 'My' и ищем сертификат
// для подписи сообщения. 
private static X509Certificate2 GetSignerCert(string signerName)
{
    // Открываем хранилище My.
    X509Store storeMy = new X509Store(StoreName.My,
        StoreLocation.CurrentUser);
    storeMy.Open(OpenFlags.ReadOnly);

    // Отображаем сертификаты для удобства работы
    // с примером.
    Log(string.Format("Найдены сертификаты следующих субъектов " +
        "в хранилище {0}:", storeMy.Name));
    foreach (X509Certificate2 cert in storeMy.Certificates)
    {
        Log(string.Format("\t{0}", cert.SubjectName.Name));
    }

    // Ищем сертификат для подписи.
    X509Certificate2Collection certColl =
        storeMy.Certificates.Find(X509FindType.FindBySubjectName,
        signerName, false);
    Log(string.Format(
        "Найдено {0} сертификат(ов) в хранилище {1} для субъекта {2}",
        certColl.Count, storeMy.Name, signerName));

    // Проверяем, что нашли требуемый сертификат
    if (certColl.Count == 0)
    {
        Log(string.Format(
            "Сертификат для данного примера не найден " +
            "в хранилище. Выберите другой сертификат для подписи. "));
        return null;
    }

    storeMy.Close();

    // Если найдено более одного сертификата,
    // возвращаем первый попавщийся.
    return certColl[0];
}

// Подписываем сообщение секретным ключем.
private static byte[] SignMsg(
    Byte[] msg,
    X509Certificate2 signerCert)
{
    // Создаем объект ContentInfo по сообщению.
    // Это необходимо для создания объекта SignedCms.
    ContentInfo contentInfo = new ContentInfo(msg);

    // Создаем объект SignedCms по только что созданному
    // объекту ContentInfo.
    // SubjectIdentifierType установлен по умолчанию в 
    // IssuerAndSerialNumber.
    // Свойство Detached устанавливаем явно в true, таким 
    // образом сообщение будет отделено от подписи.
    SignedCms signedCms = new SignedCms(contentInfo, true);

    // Определяем подписывающего, объектом CmsSigner.
    CmsSigner cmsSigner = new CmsSigner(signerCert);

    // Подписываем CMS/PKCS #7 сообение.
    Log(string.Format("Вычисляем подпись сообщения для субъекта " +
        "{0} ... ", signerCert.SubjectName.Name));
    signedCms.ComputeSignature(cmsSigner);
    Log(string.Format("Успешно."));

    // Кодируем CMS/PKCS #7 подпись сообщения.
    return signedCms.Encode();
}

// Проверяем SignedCms сообщение и возвращаем Boolean
// значение определяющее результат проверки.
private static bool VerifyMsg(Byte[] msg,
    byte[] encodedSignature)
{
    // Создаем объект ContentInfo по сообщению.
    // Это необходимо для создания объекта SignedCms.
    ContentInfo contentInfo = new ContentInfo(msg);

    // Создаем SignedCms для декодирования и проверки.
    SignedCms signedCms = new SignedCms(contentInfo, true);

    // Декодируем подпись
    signedCms.Decode(encodedSignature);

    // Перехватываем криптографические исключения, для 
    // возврата о false значения при некорректности подписи.
    try
    {
        // Проверяем подпись. В данном примере не 
        // проверяется корректность сертификата подписавшего.
        // В рабочем коде, скорее всего потребуется построение
        // и проверка корректности цепочки сертификата.
        Log(string.Format("Проверка подписи сообщения ... "));
        signedCms.CheckSignature(true);
        Log(string.Format("Успешно."));
    }
    catch (System.Security.Cryptography.CryptographicException e)
    {
        Log(string.Format("Функция VerifyMsg возбудила исключение:  {0}",
            e.Message));
        Log(string.Format("Проверка PKCS #7 сообщения завершилась " +
            "неудачно. Возможно сообщене, подпись, или " +
            "соподписи модифицированы в процессе передачи или хранения. " +
            "Подписавший или соподписавшие возможно не те " +
            "за кого себя выдают. Достоверность и/или целостность " +
            "сообщения не гарантируется. "));
        return false;
    }

    return true;
}


Ошибка падает в методе SignMsg на строчке
Код:
signedCms.ComputeSignature(cmsSigner);


Текст ошибки:
Цитата:

System.Security.Cryptography.CryptographicException: 'Could not determine signature algorithm for the signer certificate.'

This exception was originally thrown at this call stack:
System.Security.Cryptography.Pkcs.CmsSigner.Sign(System.ReadOnlyMemory<byte>, string, bool, out System.Security.Cryptography.X509Certificates.X509Certificate2Collection)
System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(System.Security.Cryptography.Pkcs.CmsSigner, bool)
System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(System.Security.Cryptography.Pkcs.CmsSigner)
Samples.CMS.DetachedSignature.SignMsg(byte[], System.Security.Cryptography.X509Certificates.X509Certificate2) in DetachedSignature.cs
Samples.CMS.DetachedSignature.MainMethod(string[], string) in DetachedSignature.cs


Помогите, пожалуйста, разобраться.
Может ли проблема быть связана сертификатом? Если для этого могут потребоваться характеристики сертификата, то я скину их.
И вообще, соответствует ли мой код задаче? К сожалению, пока что я дилетант в криптографии, пытаюсь во всем разобраться, но пока без особых успехов.

Помогите, пожалуйста Angel
Online Андрей *  
#2 Оставлено : 1 декабря 2023 г. 23:57:33(UTC)
Андрей *

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

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

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

Строка 112.
Какой сертификат находится и используется?

КриптоПро CSP установлен же и тестирование сертификата проходит без проблем?

в панели управления КриптоПро CSP\Сервис\Протестировать\По сертификату
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
Leonra_NzOe075n оставлено 04.12.2023(UTC)
Offline Leonra_NzOe075n  
#3 Оставлено : 4 декабря 2023 г. 8:55:40(UTC)
Leonra_NzOe075n

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

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

Сказал(а) «Спасибо»: 1 раз
[img=https://disk.yandex.ru/d/GzcbV9LUCxSrog]Характеристики сертификата[/img]
Автор: Андрей * Перейти к цитате
Здравствуйте.
Строка 112.
Какой сертификат находится и используется?

КриптоПро CSP установлен же и тестирование сертификата проходит без проблем?

в панели управления КриптоПро CSP\Сервис\Протестировать\По сертификату


Здравствуйте, Андрей!

Я до этого момента не тестировала, сейчас выполнила проверку по "КриптоПро CSP\Сервис\Протестировать\По сертификату". Результат: "Сертификаты недоступны. Сертификаты не отвечают критериям."

Под дебагом на строке 112 тот сертификат, который я ищу по имени субъекта. Его характеристики на скриншоте (рис. "Характеристики сертификата").

Алгоритм подписи : ГОСТ Р 34.11-2012/34.10-2012 256 бит
Алгоритм откр. кл.: ГОСТ Р 34.10-2012 256 бит (512 бит)

Проблема в том, что в сертификате нет приватного ключа, верно? Но в Exeption в тексте ошибки "System.Security.Cryptography.CryptographicException: 'Could not determine signature algorithm for the signer certificate.'" Т.е. как будто даже если бы PrivateKey был, то все равно не сработало бы.

Этот сертификат мне выдали на работе. И его "приватная часть" - это флешка. Этот сертификат - это все, что у меня есть, флешки у меня нет.

Извините, пожалуйста, за глупые вопросы. Повторюсь, для меня это новая область, пытаюсь разобраться...

Помогите, пожалуйста:
1. для того, чтобы сделать подпись запроса в формате PKCS#7 detached signature, какими характеристиками (Алгоритм подписи/Алгоритм откр. кл. и прочее) должен обладать сертификат или это не имеет значения?
2. как работать в том случае, когда приватная часть - это флешка?
3. соответствует ли мой код задаче "подпись в формате PKCS#7 detached signature"?
Online Андрей *  
#4 Оставлено : 4 декабря 2023 г. 12:54:49(UTC)
Андрей *

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

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

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

Установите личный сертификат с привязкой к флешке, через Сервис, установить личный сертификат. Там есть опция найти контейнер автоматически.

Сертификат должен быть виден и проходить тестирование.

Далее, про Pkcs7. Это стандарт 90х.
Сейчас скзи делают по умолчанию cms.

Чтобы был Pkcs7, требуется в реестре явно указать это, напишу отдельно.
Техническую поддержку оказываем тут
Наша база знаний
Online Андрей *  
#5 Оставлено : 4 декабря 2023 г. 12:56:48(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2207 раз в 1722 постах
Техническую поддержку оказываем тут
Наша база знаний
Offline Leonra_NzOe075n  
#6 Оставлено : 4 декабря 2023 г. 12:59:33(UTC)
Leonra_NzOe075n

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

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

Сказал(а) «Спасибо»: 1 раз
Автор: Андрей * Перейти к цитате
Здравствуйте.

Установите личный сертификат с привязкой к флешке, через Сервис, установить личный сертификат. Там есть опция найти контейнер автоматически.

Сертификат должен быть виден и проходить тестирование.

Далее, про Pkcs7. Это стандарт 90х.
Сейчас скзи делают по умолчанию cms.

Чтобы был Pkcs7, требуется в реестре явно указать это, напишу отдельно.


Для этого нужна флешка?
Сейчас сделала без флешки: при попытке поставить галочку "Найти контейнер автоматически" падает сообщение "Не найден контейнер, соответствующий открытому ключу сертификата"

И Вы ответили мне в ЛС, но я не могу Вам там писать больше, т.к. сайт пишет, что "У пользователя Андрей переполнен ящик входящих сообщений"
Online Андрей *  
#7 Оставлено : 4 декабря 2023 г. 14:47:58(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2207 раз в 1722 постах
если закрытый ключ в контейнере на флешке - конечно,
без доступа к нему - невозможно подписывать.
Техническую поддержку оказываем тут
Наша база знаний
Offline Leonra_NzOe075n  
#8 Оставлено : 4 декабря 2023 г. 15:12:53(UTC)
Leonra_NzOe075n

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

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

Сказал(а) «Спасибо»: 1 раз
Автор: Андрей * Перейти к цитате
если закрытый ключ в контейнере на флешке - конечно,
без доступа к нему - невозможно подписывать.


Тогда я попрошу сегодня руководителя - у него флешка.

Получается, нужно будет на его компьютере со вставленной флешкой выполнить
1. установку: Сервис\Eстановить личный сертификат\Найти контейнер автоматически
1. проверку: КриптоПро CSP\Сервис\Протестировать\По сертификату

Я отпишусь Вам о результатах.
Offline Leonra_NzOe075n  
#9 Оставлено : 5 декабря 2023 г. 12:51:27(UTC)
Leonra_NzOe075n

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

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

Сказал(а) «Спасибо»: 1 раз
Автор: Андрей * Перейти к цитате
если закрытый ключ в контейнере на флешке - конечно,
без доступа к нему - невозможно подписывать.


Андрей, здравствуйте!
На компьютере руководителя со вставленной флешкой выполнили проверку: КриптоПро CSP\Сервис\Протестировать\По сертификату
Результат:

Цитата:

Проверка завершена успешно ---> ошибок не обнаружено
Контейнер закрытого ключа ---> пользователя
Проверка целостности контейнера ---> успешно
Ключ обмена ---> доступен
длина ключа ---> 512 бит
экспорт открытого ключа ---> успешно
вычисление открытого ключа ---> успешно
импорт открытого ключа ---> успешно
подпись ---> успешно
проверка ---> успешно
создание ключа обмена ---> успешно
экспорт ключа ---> запрещен
алгоритм --->
---> ГОСТ Р 34.10-2012 DH 256 бит
---> ГОСТ Р 34.10 256 бит, параметры обмена по умолчанию
---> ГОСТ Р 34.11-2012 256 бит
---> ГОСТ 28147-89, параметры шифрования ТК26 Z
сертификат в контейнере ---> соответствует закрытому ключу
Ключ подписи ---> отсутствует
Симметричный ключ ---> отсутствует
Загрузка ключей ---> успешно
Версия контейнера ---> 2
Значение ControlKeyTimeValidity ---> 0
Режим работы CSP ---> библиотека
Расширения контейнера --->
некритическое ---> Расширение контейнера КриптоПро CSP. Срок действия ключа обмена
действителен по ---> 20 февраля 2025 г. 10:59:09


Запустили код на этом компьютер, падает ровно та же самая ошибка
Цитата:
System.Security.Cryptography.CryptographicException: "Could not determine signature algorithm for the signer certificate."


Вы написали про правки в реестре, но по ссылке конкретно про PKCS#7 я ничего не нашла.

Подскажите, пожалуйста, что делать с этой ошибкой?
Online Андрей *  
#10 Оставлено : 5 декабря 2023 г. 13:29:41(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2207 раз в 1722 постах
а версию net не уточнили, какая использовалась?

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