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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Sunchees  
#1 Оставлено : 9 апреля 2021 г. 12:03:25(UTC)
Sunchees

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

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

Добрый день!

Есть XML-документ с подписью в формате XMLDSig. Пытаемся выполнить валидацию этой подписи через cryptcp.

В документе содержится следующий блок <Signature>:

Код:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
        <Reference URI="#id-1">
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
            <DigestValue>6Im6T7+7e5HvqdLNnIo7MvkfPzaGtFXPafZnJD4naAE=</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue>Hahh6GJ8gSJwRuCFTCtX5AcQfEyFKO8VyxoIAnPRGzAAlr3zrzze1tkpHeAv8n//
2ILPAEqX3TSwFqTyln3K/w==</SignatureValue>
    <KeyInfo>
        <wsse:SecurityTokenReference>
            <wsse:Reference URI="#X-509-b4cd9b0ec38140268b4db1f31fa3e15a" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
        </wsse:SecurityTokenReference>
    </KeyInfo>
</Signature>

+ открытый ключ подписи и непосредственно тело с данными

Выполняю следующие действия:

  1. Вычисляю хэш (digest) данных, на которые ссылается <Reference URI="#id-1">:
    Код:
    cpverify.exe -mk -alg GR3411_2012_256 data.xml

    где data.xml - это прошедшие каноникализацию подписанные данные.
  2. Получаем результат в hex: E889BA4FBFBB7B91EFA9D2CD9C8A3B32F91F3F3686B455CF69F667243E276801, конвертируем данный hex в Base64, получаем: 6Im6T7+7e5HvqdLNnIo7MvkfPzaGtFXPafZnJD4naAE=
  3. Видим, что рассчитанный хэш соответствует значению в <DigestValue> в исходном документе, следовательно переходим к проверке самой подписи.
  4. Высчитываем хэш (digest) для блока <SignedInfo>:
    Код:
    cpverify.exe -mk -alg GR3411_2012_256 signedInfo.xml

    где signedInfo.xml содержит данные:
    Код:
    <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod><SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"></SignatureMethod><Reference URI="#id-1"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform></Transforms><DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"></DigestMethod><DigestValue>6Im6T7+7e5HvqdLNnIo7MvkfPzaGtFXPafZnJD4naAE=</DigestValue></Reference></SignedInfo>

  5. Получаем результат в hex: FDEBB94EB1CE9975D162A571B2139CE2DF1CE34DE732D2612437C62F80B45902, конвертируем данный hex в Base64, получаем /eu5TrHOmXXRYqVxshOc4t8c403nMtJhJDfGL4C0WQI=
  6. Устанавливаем открытый ключ из исходного документа в хранилище. Получаем отпечаток: f3b370b04ad23d25fb2f19316434cf268ff0955e
  7. Пытаемся проверить подпись, выполняя команду:
    Код:
    cryptcp -nochain -vsignf digest.txt -thumbprint f3b370b04ad23d25fb2f19316434cf268ff0955e

    где digest.txt - это хэш (в Base64), полученный на шаге 5
    рядом с digest.txt лежит файл digest.txt.sgn, который содержит в себе значение элемента <SignatureValue>
  8. Получаем ответ [ErrorCode: 0xffffffff] без каких-либо дополнительных комментариев.


Вижу, что подпись в <SignatureValue> по сути не содержит информации о сертификате, из чего могу предположить, что нужно либо добавить какие-то параметры в вызов cryptcp на шаге 7, либо вообще использовать какую-то другую команду.

Хочу понять, как правильно выполнять валидацию такой подписи, и возможно ли это вообще через консольные утилиты КриптоПро?

Исходный XML-документ пробовал проверять через https://dss.cryptopro.ru/Verify/, там валидация прошла успешно, из чего делаю вывод, что проблема не в самом документе, а именно в нашем алгоритме его валидации.

Из того что нашел на просторах интернета и данного форума, вижу что как правило валидацию XMLDSig выполняют с помощью .NET или Java SDK, но прежде чем переходить к такой реализации, хочу убедиться что других вариантов нет.
Сервис валидации подписи у нас написан на NodeJS, взаимодействуем с КриптоПро как раз путем вызова консольных команд. При этом сервис нормально проверяет подписи, сформированные например через CryptoPro Browser Plugin, т.е. подписи которые в себе также содержат информацию о сертификате.
Offline two_oceans  
#2 Оставлено : 15 апреля 2021 г. 8:33:26(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 393 раз в 366 постах
Добрый день.
На форуме где-то был пример валидации XMLDSig через утилиты, этот путь возможен (нужна проверка raw подписи, cryptcp вероятно не подойдет). Очевидна только одна проблема - если у Вас несколько процессов NodeJS проводят валидацию параллельно, то они должны использовать разные папки или разные имена файлов, чтобы в процессе проверки разные подписи не смешивались и не давали ошибки.

Заметки по алгоритму.
https://www.cryptopro.ru/forum2/default.aspx?g=posts&t=11684 ответ про Raw в cryptcp

Раз уж у Вас NodeJS, может быть там получится использовать проверку Raw подписи через плагин и Javascript?
https://docs.cryptopro.r...in-samples-raw-signature

Отредактировано пользователем 15 апреля 2021 г. 8:36:33(UTC)  | Причина: Не указана

Offline Sunchees  
#3 Оставлено : 19 апреля 2021 г. 13:12:40(UTC)
Sunchees

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

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

Спасибо за ответ.

Цитата:
Очевидна только одна проблема - если у Вас несколько процессов NodeJS проводят валидацию параллельно, то они должны использовать разные папки или разные имена файлов, чтобы в процессе проверки разные подписи не смешивались и не давали ошибки.

Да, у нас для валидации каждой подписи формируется отдельная временная папка.

Цитата:
Раз уж у Вас NodeJS, может быть там получится использовать проверку Raw подписи через плагин и Javascript?

На этот плагин я смотрел, но насколько я понял, он под капотом использует CryptoPro Browser-PlugIn, который просто так на NodeJS, не завести, т.к. это именно браузерный плагин.

Цитата:
есть ответ 4 года назад что cryptcp не подходит, можете использовать csptest или за 5 минут сделать свою утилиту

Подскажите пожалуйста, что имеете ввиду под "за 5 минут сделать свою утилиту"? Разве подпись сформированную по ГОСТу можно без криптопровайдера проверить?

Попробовал проверить подпись через csptest, но судя по всему застрял на переводе Base64-подписи в DER. Поясню:


  1. Сохраняю Base64-содержимое сертификата в файл cert.cer
  2. Сохраняю каноникализированный <SignedInfo> в файл signedInfo.xml
  3. Декодирую из Base64 содержимое тега <SignatureValue>, сохраняю в файл signedInfo.xml.sng
  4. Выполняю команду:
    Код:
    csptest.exe -keys -verify GOST12_256 -in C:\sig-test\1\signed-info.xml -signature C:\sig-test\1\signed-info.xml.sgn -keytype signature -certificate C:\sig-test\1\cert.cer
    


    Получаю в ответ:

    Код:
    CSP (Type:80) v4.0.9019 KC1 Release Ver:4.0.9969 OS:Windows CPU:IA32 FastCode:READY:SSSE3.
    AcquireContext: OK. HCRYPTPROV: 21807288
    GetProvParam(PP_NAME): Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider
    Public key imported from cert file: C:\sig-test\1\cert.cer
    Hash object created with alg: GOST12_256 0x8021
    The data buffer has been hashed.
    An error occurred in running the program.
    ctkey.c:3534:Bad Signature.
    Error number 0x80090006 (-2146893818).
    Неправильная подпись.
    
    Total: SYS: 0,031 sec USR: 0,047 sec UTC: 0,176 sec
    [ErrorCode: 0x80090006]
    



Попробовал пойти в обратном порядке, сделал следующие действия:

  1. Сформировал тестовый сертификат для подписи, сохранил в локальном хранилище, публичный ключ экспортировал в файл test-signer.cer
  2. Выполняю команду:
    Код:
    csptest.exe -keys -sign GOST12_256 -in C:\sig-test\1\signed-info.xml -out C:\sig-test\1\signed-info.xml.self-signed.sgn -keytype signature -cont default
    

  3. Выбираю контейнер со сформированным сертификатом для подписи.
  4. В ответ получаю:
    Код:
    CSP (Type:80) v4.0.9019 KC1 Release Ver:4.0.9969 OS:Windows CPU:IA32 FastCode:READY:SSSE3.
    AcquireContext: OK. HCRYPTPROV: 13710280
    GetProvParam(PP_NAME): Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider
    Container name: "58401f2db-2059-b990-d56b-e2ab0af28cf"
    Signature key is available. HCRYPTKEY: 0xd2ffb0
    Hash object created with alg: GOST12_256 0x8021
    The data buffer has been hashed.
    Signature length 64 found.
    Signature was done.
    Output file (C:\sig-test\1\signed-info.xml.self-signed.sgn) has been saved
    Signature saved into file C:\sig-test\1\signed-info.xml.self-signed.sgn
    
    Keys in container:
      signature key
    Extensions:
      OID: 1.2.643.2.2.37.3.9
      PrivKey: Not specified - 15.07.2022 16:39:41 (UTC)
    Total: SYS: 0,438 sec USR: 0,219 sec UTC: 6,106 sec
    [ErrorCode: 0x00000000]
    


  5. Проверяю сформированную только что подпись:
    Код:
    csptest.exe -keys -verify GOST12_256 -in C:\sig-test\1\signed-info.xml -signature C:\sig-test\1\signed-info.xml.self-signed.sgn -keytype signature -certificate C:\sig-test\1\test-signer.cer
    

  6. В ответ получаю:
    Код:
    CSP (Type:80) v4.0.9019 KC1 Release Ver:4.0.9969 OS:Windows CPU:IA32 FastCode:READY:SSSE3.
    AcquireContext: OK. HCRYPTPROV: 16274368
    GetProvParam(PP_NAME): Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider
    Public key imported from cert file: C:\sig-test\1\test-signer.cer
    Hash object created with alg: GOST12_256 0x8021
    The data buffer has been hashed.
    Signature was verified OK
    
    Total: SYS: 0,031 sec USR: 0,047 sec UTC: 0,134 sec
    [ErrorCode: 0x00000000]
    



Т.е. подпись сформировал и проверил, вроде бы все ок.
Дальше пытаюсь проверить эту подпись в контексте всего XML-документа.

  1. В исходном XML-файле заменяю сертификат на содержимое файла test-signer.cer
  2. Содержимое файла с полученной подписью (signed-info.xml.self-signed.sgn) кодирую в Base64, и помещаю в элемент <SignatureValue>
  3. Полученный файл пытаюсь проверить через https://dss.cryptopro.ru/Verify/ - получаю ошибку. Как уже писал ранее, исходный XML через данный сервис проверяется корректно.


При этом в моем понимании, так как подпись формируется только на SignedInfo, а он у меня остался неизменным, то такая "ручная подмена" подписи и сертификата должны сработать.

Если так, то в итоге могу предположить что где-то на этапе преобразования подписи в Base64 что-то идет не так. Либо где-то не соответствуют алгоритмы подписания, хотя я везде использовал GOST 2012 256, как указано в алгоритмах из <SignedInfo>
Offline Андрей Русев  
#4 Оставлено : 23 апреля 2021 г. 15:57:30(UTC)
Русев Андрей

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

Группы: Администраторы, Участники
Зарегистрирован: 16.04.2008(UTC)
Сообщений: 1,260

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 442 раз в 322 постах
Здравствуйте.
Вероятно, вам надо перевернуть значение подписи:
https://www.cryptopro.ru....aspx?g=posts&t=8062
Официальная техподдержка. Официальная база знаний.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.