Статус: Участник
Группы: Участники
Зарегистрирован: 20.12.2012(UTC) Сообщений: 29 Откуда: Москва
Сказал(а) «Спасибо»: 1 раз
|
Подскажите, как и для чего используются pycades.Store().Name() и pycades.Store().Location()? Обе эти функции вываливают ошибки. Есть скрипт: Код:
import sys
import pprint
sys.path.append('/opt/pycades/')
import pycades
certThumb = '610A3........7CB647';
store = pycades.Store();
store.Open(pycades.CADESCOM_LOCAL_MACHINE_STORE, pycades.CAPICOM_MY_STORE, pycades.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED)
#print(store.Name());
#print(store.Location());
certs = store.Certificates
inData = ''
for line in sys.stdin:
inData = inData + line
for i in range(certs.Count):
cert = certs.Item(i + 1)
if cert.Thumbprint == certThumb:
envelopedData = pycades.EnvelopedData()
envelopedData.Content = inData
envelopedData.Recipients.Add(cert)
encryptedMessage = envelopedData.Encrypt(pycades.CADESCOM_ENCODE_BASE64)
print(encryptedMessage)
Всё настроено, сообщения шифруются и расшифровываются (другим скриптом) Однако, если раскоментировать один из #print, то вываливается ошибка Код:Traceback (most recent call last):
File "encrypt.py", line 10, in <module>
print(store.Name());
TypeError: 'str' object is not callable
Такая же ошибка и для Location Отредактировано пользователем 9 сентября 2021 г. 11:45:02(UTC)
| Причина: Не указана
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
https://docs.cryptopro.r...com/cadescom_class/storeПолагаю там просто лишние скобочки, ведь к store.Certificates обращаетесь без скобок? Код:print(store.Name);
print(store.Location);
Так не пробовали? Цитата:Но судя по комментариям разработки принимающего продукта, у них формирование происходит именно по изначальному документа. Учитывая, что у них используется JCP, судя по всему выполняется что-то подобное JCPxml.dsig.internal.xmldsigri.tests.SignFileExample.
Вопрос: можно ли что-то аналогичное реализовать на pycades? Есть какой-то эталонный пример от них? Скорее всего нужно немного перебирать параметры в стандартном примере. https://docs.cryptopro.r.../pycades-sign-verify-xmlОтредактировано пользователем 9 сентября 2021 г. 12:09:01(UTC)
| Причина: Не указана
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 03.09.2021(UTC) Сообщений: 7
Сказал(а) «Спасибо»: 2 раз
|
Автор: two_oceans https://docs.cryptopro.ru/cades/reference/cadescom/cadescom_class/store Полагаю там просто лишние скобочки, ведь к store.Certificates обращаетесь без скобок? Код:print(store.Name);
print(store.Location);
Так не пробовали? Цитата:Но судя по комментариям разработки принимающего продукта, у них формирование происходит именно по изначальному документа. Учитывая, что у них используется JCP, судя по всему выполняется что-то подобное JCPxml.dsig.internal.xmldsigri.tests.SignFileExample.
Вопрос: можно ли что-то аналогичное реализовать на pycades? Есть какой-то эталонный пример от них? Скорее всего нужно немного перебирать параметры в стандартном примере. https://docs.cryptopro.r.../pycades-sign-verify-xml Пример подписи выглядит вот так: Код:<?xml version="1.0" encoding="UTF-8"?>
<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="">
<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
<DigestValue>WHK6jue2Wj/NULNiQv2yMyc2j+zMMI9EOuNKSQ4MCZU=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>6jmckUC/XFmmcE0xPq2ZS3x2XjRhyhp22eer2mNq9CeHccWHHoTv9aWQT+HAlQl85V3EfWvEZoBN1lOMUcVqew==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIDYzCCAxKgAwIBAgITEgBXp+ja4olD1vlmtQABAFen6DAIBgYqhQMCAgMwfzEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBjcnlwdG9wcm8ucnUxCzAJBgNVBAYTAlJVMQ8wDQYDVQQHEwZNb3Njb3cxFzAVBgNVBAoTDkNSWVBUTy1QUk8gTExDMSEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDIwHhcNMjEwODE5MDkzNjAyWhcNMjExMTE5MDk0NjAyWjBpMSIwIAYJKoZIhvcNAQkBFhNmc3NwbnNvNTRAZ21haWwuY29tMRkwFwYDVQQDDBBiYXJzX3Rlc3RfaXZhbm92MQswCQYDVQQLDAJQUDENMAsGA1UECgwEQmFyczEMMAoGA1UEBwwDTnNrMGYwHwYIKoUDBwEBAQEwEwYHKoUDAgIkAAYIKoUDBwEBAgIDQwAEQIq8QBY4b8lt/WUkYOrugNgvj2luOE0H1U5m3iEE9od4BknQcZN31MpZRHf7i7hCf/uIdZKkSGF7LYD6IL0PToSjggF2MIIBcjAOBgNVHQ8BAf8EBAMCBPAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFCqbX3NAwMmNvTdxEQgGaeMqHI1hMB8GA1UdIwQYMBaAFE6DPhRp7+xdepUrXxH+NzIWSVUrMFwGA1UdHwRVMFMwUaBPoE2GS2h0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L0NlcnRFbnJvbGwvQ1JZUFRPLVBSTyUyMFRlc3QlMjBDZW50ZXIlMjAyKDEpLmNybDCBrAYIKwYBBQUHAQEEgZ8wgZwwZAYIKwYBBQUHMAKGWGh0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L0NlcnRFbnJvbGwvdGVzdC1jYS0yMDE0X0NSWVBUTy1QUk8lMjBUZXN0JTIwQ2VudGVyJTIwMigxKS5jcnQwNAYIKwYBBQUHMAGGKGh0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L29jc3Avb2NzcC5zcmYwCAYGKoUDAgIDA0EAQeupGwzoecSEV2Z0cBE8n7zyM8Ctxzh6Rw7p33/QIKBoLTiy8V0j7tkrbApc1ivuUn5ohQWV4pB2jMsbIxwonA==</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
Я уже посмотрел исходники, которые они прислали и получается, что они не используют cades, а через JCP создают отдельно DigestValue, SignatureValue и X509Certificate. И если я правильно понимаю, в таком случае именно через подписание XML такой структуры от pycades не добиться. Поэтому возникает вопрос: можно ли с помощью pycades отдельно создать DigestValue и SignatureValue? Сейчас смотрю примеры по обычному подписанию строк, но если есть еще мысли, как сделать более правильно - буду благодарен за совет!
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Данный пример является некорректным в плане того, что: 1) когда подпись в отдельном файле по стандарту в URI должен указываться исходный файл; 2) не указан трансформ каноникализации подписываемого фрагмента. Считают как есть хэш файла? Такой вариант может применяться для xmldsig подписи двоичного файла, но немного натянут для исходного файла в формате xml. В том смысле, что парсер просто при загрузке xml файла его может изменить, например, откорректировав переводы строк. Либо я неправильно понял и подписывается действительно двоичный файл? Для двоичного файла хэш можно посчитать через https://docs.cryptopro.r...scom_class/cphasheddata, но будет много хлопот чтобы загрузить файл без искажения, например придется кодировать в base64. Raw подпись можно вычислить через https://docs.cryptopro.r...escom_class/rawsignatureОднако если делать вручную надо еще и вручную каноникализировать SignedInfo. Как это сделать на питоне я не смогу подсказать. Как близкое приближение для xml на ум приходит: сделать ENVELOPED подпись копии всего исходного файла, из результата вырезать тег Signature в отдельный файл. Передать вырезанный Signature в паре с исходным файлом, а не с тем что получилось после подписи. Там будет "лишний" относительно примера трансформ enveloped_signature, но он будет работать "вхолостую" в случае отдельного файла (ничего не поменяет). Поэтому если принимающая сторона на самом трансформе не запнется (а просто скопируют значения хэша и подписи), то хэш и подпись должны сойтись. Конечно, если подпись по их версии от SignedInfo, а не от чего-то другого. Отредактировано пользователем 9 сентября 2021 г. 13:23:52(UTC)
| Причина: Не указана
|
1 пользователь поблагодарил two_oceans за этот пост.
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 03.09.2021(UTC) Сообщений: 7
Сказал(а) «Спасибо»: 2 раз
|
Автор: two_oceans Данный пример является некорректным в плане того, что: 1) когда подпись в отдельном файле по стандарту в URI должен указываться исходный файл; 2) не указан трансформ каноникализации подписываемого фрагмента. Считают как есть хэш файла? Такой вариант может применяться для xmldsig подписи двоичного файла, но немного натянут для исходного файла в формате xml. В том смысле, что парсер просто при загрузке xml файла его может изменить, например, откорректировав переводы строк. Либо я неправильно понял и подписывается действительно двоичный файл? Для двоичного файла хэш можно посчитать через https://docs.cryptopro.r...scom_class/cphasheddata, но будет много хлопот чтобы загрузить файл без искажения, например придется кодировать в base64. Raw подпись можно вычислить через https://docs.cryptopro.r...escom_class/rawsignatureОднако если делать вручную надо еще и вручную каноникализировать SignedInfo. Как это сделать на питоне я не смогу подсказать. Как близкое приближение для xml на ум приходит: сделать ENVELOPED подпись копии всего исходного файла, из результата вырезать тег Signature в отдельный файл. Передать вырезанный Signature в паре с исходным файлом, а не с тем что получилось после подписи. Там будет "лишний" относительно примера трансформ enveloped_signature, но он будет работать "вхолостую" в случае отдельного файла (ничего не поменяет). Поэтому если принимающая сторона на самом трансформе не запнется (а просто скопируют значения хэша и подписи), то хэш и подпись должны сойтись. Конечно, если подпись по их версии от SignedInfo, а не от чего-то другого. Спасибо большое за ответы! Сейчас разбор дошел до следующего - на принимающей стороне есть код: Код:
private fun messageDigest(): MessageDigest {
return MessageDigest.getInstance(GOST3411_2012_256, JCP_PROVIDER)
}
private fun hash(data: ByteArray): ByteArray {
val messageDigest = messageDigest()
messageDigest.update(data)
return messageDigest.digest()
}
Повторить массив байтов data получается. Если делать на стороне pycades что-то аналогичное: Код:
hashedData = pycades.HashedData()
hashedData.Algorithm = pycades.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256
hashedData.Hash('<languages>\n</languages>')
print(hashedData.Value)
то получается совсем другой результат. Вопрос: есть ли какая-то возможность повторить алгоритм из примера на java в pycades?
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Посмотрите, не получилась ли перевернутая строка, при необходимости просто переверните. Первый байт с последним, второй с предпоследним. Если результат объявлен как массив байтов и размер массива совпадает с размером результата, то reverse массива делает как раз что нужно. Это, может показаться странным, но сам по себе гост не регламентирует форму выдачи результата - младший байт по младшему адресу или старший байт по младшему адресу, нужно смотреть в инструкции какую форму выдает конкретное средство расчета хэша. В самом гост числа записаны одной строкой по аналогии с десятичной системой счисления, то есть старший байт в начале записи. Для указания в файле xml двоичных криптографических данных зарубежным стандартом также предлагается такой формат записи. Однако, для процессоров Intel исторически используется принцип хранения данных в памяти младший байт по младшему адресу. Разные средства используют разный подход. Можно использовать стандартные примеры из стандарта гост-2012 для калибровки в какой форме возвращен результат. Навскидку правда я не нашел тестовые файлики с нужными строками. Для строки, что приведена в примере у меня получаются такие результаты: Код:1) \n остался как есть, не переведен в перевод строки:
997D40716B671649DB3D386EFAF2B4E6756DC8F2F294D3929FB81FFF5050ADC2
mX1AcWtnFknbPThu+vK05nVtyPLylNOSn7gf/1BQrcI=
С переворотом:
C2AD5050FF1FB89F92D394F2F2C86D75E6B4F2FA6E383DDB4916676B71407D99
wq1QUP8fuJ+S05Ty8shtdea08vpuOD3bSRZna3FAfZk=
2) \n заменен на символы 13 10
A990408559D02FBFBD79C66BA8ED0BCFFC81AB56D8E5B7C717A8B3F64F6884EA
qZBAhVnQL7+9ecZrqO0Lz/yBq1bY5bfHF6iz9k9ohOo=
С переворотом:
EA84684FF6B3A817C7B7E5D856AB81FCCF0BEDA86BC679BDBF2FD059854090A9
6oRoT/azqBfHt+XYVquB/M8L7ahrxnm9vy/QWYVAkKk=
3) \n заменен на символ 10
DC4A10B5F800D5BB2BF0CCDC00BF7C0C8B064ED38EAEE63F5F80AD9F79697B3B
3EoQtfgA1bsr8MzcAL98DIsGTtOOruY/X4Ctn3lpezs=
С переворотом:
3B7B69799FAD805F3FE6AE8ED34E068B0C7CBF00DCCCF02BBBD500F8B5104ADC
O3tpeZ+tgF8/5q6O004Giwx8vwDczPAru9UA+LUQStw=
Если не получился ни один вариант, то возможно передача строки некорректная. Если получились варианты с переворотом, не забудьте перевернуть. Насчет преобразования перевода строки - вопрос немного другой, к плагину/расширению отношения не имеет, зависит от самого языка программы.
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 03.09.2021(UTC) Сообщений: 7
Сказал(а) «Спасибо»: 2 раз
|
Автор: two_oceans Посмотрите, не получилась ли перевернутая строка, при необходимости просто переверните. Первый байт с последним, второй с предпоследним. Если результат объявлен как массив байтов и размер массива совпадает с размером результата, то reverse массива делает как раз что нужно. Это, может показаться странным, но сам по себе гост не регламентирует форму выдачи результата - младший байт по младшему адресу или старший байт по младшему адресу, нужно смотреть в инструкции какую форму выдает конкретное средство расчета хэша. В самом гост числа записаны одной строкой по аналогии с десятичной системой счисления, то есть старший байт в начале записи. Для указания в файле xml двоичных криптографических данных зарубежным стандартом также предлагается такой формат записи. Однако, для процессоров Intel исторически используется принцип хранения данных в памяти младший байт по младшему адресу. Разные средства используют разный подход. Можно использовать стандартные примеры из стандарта гост-2012 для калибровки в какой форме возвращен результат. Навскидку правда я не нашел тестовые файлики с нужными строками. Для строки, что приведена в примере у меня получаются такие результаты: Код:1) \n остался как есть, не переведен в перевод строки:
997D40716B671649DB3D386EFAF2B4E6756DC8F2F294D3929FB81FFF5050ADC2
mX1AcWtnFknbPThu+vK05nVtyPLylNOSn7gf/1BQrcI=
С переворотом:
C2AD5050FF1FB89F92D394F2F2C86D75E6B4F2FA6E383DDB4916676B71407D99
wq1QUP8fuJ+S05Ty8shtdea08vpuOD3bSRZna3FAfZk=
2) \n заменен на символы 13 10
A990408559D02FBFBD79C66BA8ED0BCFFC81AB56D8E5B7C717A8B3F64F6884EA
qZBAhVnQL7+9ecZrqO0Lz/yBq1bY5bfHF6iz9k9ohOo=
С переворотом:
EA84684FF6B3A817C7B7E5D856AB81FCCF0BEDA86BC679BDBF2FD059854090A9
6oRoT/azqBfHt+XYVquB/M8L7ahrxnm9vy/QWYVAkKk=
3) \n заменен на символ 10
DC4A10B5F800D5BB2BF0CCDC00BF7C0C8B064ED38EAEE63F5F80AD9F79697B3B
3EoQtfgA1bsr8MzcAL98DIsGTtOOruY/X4Ctn3lpezs=
С переворотом:
3B7B69799FAD805F3FE6AE8ED34E068B0C7CBF00DCCCF02BBBD500F8B5104ADC
O3tpeZ+tgF8/5q6O004Giwx8vwDczPAru9UA+LUQStw=
Если не получился ни один вариант, то возможно передача строки некорректная. Если получились варианты с переворотом, не забудьте перевернуть. Насчет преобразования перевода строки - вопрос немного другой, к плагину/расширению отношения не имеет, зависит от самого языка программы. Пробую сейчас сделать приведенные варианты. И почему-то ни один у меня по хэшу не совпадает. Можете показать пример того, как получается хэш в Вашем случае? UPD: Прочитал определенный блок документации, первый пример получился, буду идти дальше. Спасибо! Отредактировано пользователем 14 сентября 2021 г. 11:54:15(UTC)
| Причина: Не указана
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 27.07.2021(UTC) Сообщений: 3
|
Добрый день! Подскажите как снять(не проверка, а именно снять) подпись PKCS7 с помощью pycades?
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 03.09.2021(UTC) Сообщений: 7
Сказал(а) «Спасибо»: 2 раз
|
Автор: Dmitriy Chernyshov Автор: two_oceans Посмотрите, не получилась ли перевернутая строка, при необходимости просто переверните. Первый байт с последним, второй с предпоследним. Если результат объявлен как массив байтов и размер массива совпадает с размером результата, то reverse массива делает как раз что нужно. Это, может показаться странным, но сам по себе гост не регламентирует форму выдачи результата - младший байт по младшему адресу или старший байт по младшему адресу, нужно смотреть в инструкции какую форму выдает конкретное средство расчета хэша. В самом гост числа записаны одной строкой по аналогии с десятичной системой счисления, то есть старший байт в начале записи. Для указания в файле xml двоичных криптографических данных зарубежным стандартом также предлагается такой формат записи. Однако, для процессоров Intel исторически используется принцип хранения данных в памяти младший байт по младшему адресу. Разные средства используют разный подход. Можно использовать стандартные примеры из стандарта гост-2012 для калибровки в какой форме возвращен результат. Навскидку правда я не нашел тестовые файлики с нужными строками. Для строки, что приведена в примере у меня получаются такие результаты: Код:1) \n остался как есть, не переведен в перевод строки:
997D40716B671649DB3D386EFAF2B4E6756DC8F2F294D3929FB81FFF5050ADC2
mX1AcWtnFknbPThu+vK05nVtyPLylNOSn7gf/1BQrcI=
С переворотом:
C2AD5050FF1FB89F92D394F2F2C86D75E6B4F2FA6E383DDB4916676B71407D99
wq1QUP8fuJ+S05Ty8shtdea08vpuOD3bSRZna3FAfZk=
2) \n заменен на символы 13 10
A990408559D02FBFBD79C66BA8ED0BCFFC81AB56D8E5B7C717A8B3F64F6884EA
qZBAhVnQL7+9ecZrqO0Lz/yBq1bY5bfHF6iz9k9ohOo=
С переворотом:
EA84684FF6B3A817C7B7E5D856AB81FCCF0BEDA86BC679BDBF2FD059854090A9
6oRoT/azqBfHt+XYVquB/M8L7ahrxnm9vy/QWYVAkKk=
3) \n заменен на символ 10
DC4A10B5F800D5BB2BF0CCDC00BF7C0C8B064ED38EAEE63F5F80AD9F79697B3B
3EoQtfgA1bsr8MzcAL98DIsGTtOOruY/X4Ctn3lpezs=
С переворотом:
3B7B69799FAD805F3FE6AE8ED34E068B0C7CBF00DCCCF02BBBD500F8B5104ADC
O3tpeZ+tgF8/5q6O004Giwx8vwDczPAru9UA+LUQStw=
Если не получился ни один вариант, то возможно передача строки некорректная. Если получились варианты с переворотом, не забудьте перевернуть. Насчет преобразования перевода строки - вопрос немного другой, к плагину/расширению отношения не имеет, зависит от самого языка программы. Пробую сейчас сделать приведенные варианты. И почему-то ни один у меня по хэшу не совпадает. Можете показать пример того, как получается хэш в Вашем случае? UPD: Прочитал определенный блок документации, первый пример получился, буду идти дальше. Спасибо! В итоге, победил первую часть, сошлись на замене \n. Но сейчас пошла вторая часть - у нас есть digest, теперь нужно получить подпись. И здесь я опять не совсем понимаю, что происходит в jcp: Код:
fun makeSign(
// Здесь получили digest
val dataDigestValueBase64 = toBase64(dataDigestValue)
// Здесь сформировали xml-строку
val signInfoXml = formatSignedInfoXml(dataDigestValueBase64)
// Здесь сформировали "базу" для подписи
val signature = getSignature()
val privateKey = getPrivateKey(currentCert.encoded)
signature.initSign(privateKey)
signature.update(signInfoXml.toByteArray())
val sign = signature.sign()
private fun formatSignedInfoXml(digestValue: String): String {
return "<SignedInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><CanonicalizationMethod Algorithm=\"$CANONICALIZATION_ALGORITHM\"></CanonicalizationMethod><SignatureMethod Algorithm=\"$GOSTR34102012_GOSTR34112012_256_URN\"></SignatureMethod><Reference URI=\"\"><DigestMethod Algorithm=\"$GOSTR34112012_256_URN\"></DigestMethod><DigestValue>$digestValue</DigestValue></Reference></SignedInfo>"
}
private fun getSignature(): Signature {
return Signature.getInstance("GOST3411_2012_256withGOST3410DH_2012_256", JCP_PROVIDER)
}
Вот в момент получения getSignature мне непонятно, что это в итоге за подпись будет? Cades-BES? Или это RawSignature? И можно ли аналоги сделать на pycades? Если судить дальше по примеру полученного base64 от подписи - это не Cades-BES: Код:
6jmckUC/XFmmcE0xPq2ZS3x2XjRhyhp22eer2mNq9CeHccWHHoTv9aWQT+HAlQl85V3EfWvEZoBN1lOMUcVqew==
Отредактировано пользователем 16 сентября 2021 г. 14:58:21(UTC)
| Причина: Не указана
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 03.09.2021(UTC) Сообщений: 7
Сказал(а) «Спасибо»: 2 раз
|
Автор: Dmitriy Chernyshov Автор: Dmitriy Chernyshov Автор: two_oceans Посмотрите, не получилась ли перевернутая строка, при необходимости просто переверните. Первый байт с последним, второй с предпоследним. Если результат объявлен как массив байтов и размер массива совпадает с размером результата, то reverse массива делает как раз что нужно. Это, может показаться странным, но сам по себе гост не регламентирует форму выдачи результата - младший байт по младшему адресу или старший байт по младшему адресу, нужно смотреть в инструкции какую форму выдает конкретное средство расчета хэша. В самом гост числа записаны одной строкой по аналогии с десятичной системой счисления, то есть старший байт в начале записи. Для указания в файле xml двоичных криптографических данных зарубежным стандартом также предлагается такой формат записи. Однако, для процессоров Intel исторически используется принцип хранения данных в памяти младший байт по младшему адресу. Разные средства используют разный подход. Можно использовать стандартные примеры из стандарта гост-2012 для калибровки в какой форме возвращен результат. Навскидку правда я не нашел тестовые файлики с нужными строками. Для строки, что приведена в примере у меня получаются такие результаты: Код:1) \n остался как есть, не переведен в перевод строки:
997D40716B671649DB3D386EFAF2B4E6756DC8F2F294D3929FB81FFF5050ADC2
mX1AcWtnFknbPThu+vK05nVtyPLylNOSn7gf/1BQrcI=
С переворотом:
C2AD5050FF1FB89F92D394F2F2C86D75E6B4F2FA6E383DDB4916676B71407D99
wq1QUP8fuJ+S05Ty8shtdea08vpuOD3bSRZna3FAfZk=
2) \n заменен на символы 13 10
A990408559D02FBFBD79C66BA8ED0BCFFC81AB56D8E5B7C717A8B3F64F6884EA
qZBAhVnQL7+9ecZrqO0Lz/yBq1bY5bfHF6iz9k9ohOo=
С переворотом:
EA84684FF6B3A817C7B7E5D856AB81FCCF0BEDA86BC679BDBF2FD059854090A9
6oRoT/azqBfHt+XYVquB/M8L7ahrxnm9vy/QWYVAkKk=
3) \n заменен на символ 10
DC4A10B5F800D5BB2BF0CCDC00BF7C0C8B064ED38EAEE63F5F80AD9F79697B3B
3EoQtfgA1bsr8MzcAL98DIsGTtOOruY/X4Ctn3lpezs=
С переворотом:
3B7B69799FAD805F3FE6AE8ED34E068B0C7CBF00DCCCF02BBBD500F8B5104ADC
O3tpeZ+tgF8/5q6O004Giwx8vwDczPAru9UA+LUQStw=
Если не получился ни один вариант, то возможно передача строки некорректная. Если получились варианты с переворотом, не забудьте перевернуть. Насчет преобразования перевода строки - вопрос немного другой, к плагину/расширению отношения не имеет, зависит от самого языка программы. Пробую сейчас сделать приведенные варианты. И почему-то ни один у меня по хэшу не совпадает. Можете показать пример того, как получается хэш в Вашем случае? UPD: Прочитал определенный блок документации, первый пример получился, буду идти дальше. Спасибо! В итоге, победил первую часть, сошлись на замене \n. Но сейчас пошла вторая часть - у нас есть digest, теперь нужно получить подпись. И здесь я опять не совсем понимаю, что происходит в jcp: Код:
fun makeSign(
// Здесь получили digest
val dataDigestValueBase64 = toBase64(dataDigestValue)
// Здесь сформировали xml-строку
val signInfoXml = formatSignedInfoXml(dataDigestValueBase64)
// Здесь сформировали "базу" для подписи
val signature = getSignature()
val privateKey = getPrivateKey(currentCert.encoded)
signature.initSign(privateKey)
signature.update(signInfoXml.toByteArray())
val sign = signature.sign()
private fun formatSignedInfoXml(digestValue: String): String {
return "<SignedInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><CanonicalizationMethod Algorithm=\"$CANONICALIZATION_ALGORITHM\"></CanonicalizationMethod><SignatureMethod Algorithm=\"$GOSTR34102012_GOSTR34112012_256_URN\"></SignatureMethod><Reference URI=\"\"><DigestMethod Algorithm=\"$GOSTR34112012_256_URN\"></DigestMethod><DigestValue>$digestValue</DigestValue></Reference></SignedInfo>"
}
private fun getSignature(): Signature {
return Signature.getInstance("GOST3411_2012_256withGOST3410DH_2012_256", JCP_PROVIDER)
}
Вот в момент получения getSignature мне непонятно, что это в итоге за подпись будет? Cades-BES? Или это RawSignature? И можно ли аналоги сделать на pycades? Если судить дальше по примеру полученного base64 от подписи - это не Cades-BES: Код:
6jmckUC/XFmmcE0xPq2ZS3x2XjRhyhp22eer2mNq9CeHccWHHoTv9aWQT+HAlQl85V3EfWvEZoBN1lOMUcVqew==
UPD: Попробовал разные варианты, и если я правильно понимаю, то это RawSignature, в которой подписали хеш SignedInfo. Так ли это?
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close