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

Уведомление

Icon
Error

3 Страницы123>
Опции
К последнему сообщению К первому непрочитанному
Offline Dmitrii F  
#1 Оставлено : 27 мая 2020 г. 17:10:27(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Здравствуйте!

С помощью утилиты openssl, дополненной gost engine (https://github.com/gost-engine/engine/)
была создана откреплённая подпись для xml файла. Для подписи использовались алгоритмы
gost2012_256.

При создании сертификата и ключа выполнялись следующие команды:

Код:

openssl req -newkey gost2012_256 -nodes -pkeyoptparamset:A -out c.csr -keyout example.key
openssl x509 -req -in c.csr -out example.pem -signkey example.key -days 365


При создании откреплённой подписи выполнялись следующие команды:
Код:

openssl dgst -binary -md_gost12_256 path_to/canonicalizated.xml #получение digest
openssl dgst -sign private_key -binary -md_gost12_256 digest_value #получение значения signature, 
#private_key - ключ, digest_value - полученное ранее значение digest

Для канонизации xml использовался метод lxml.etree.tostring Python.

Значения digest и signature, а также сертификата использовались для формирования
откреплённой подписи xml.
Прикрепляю архив с исходными файлами:
example.zip (2kb) загружен 9 раз(а).
, где:
example.pem - сертификат
in_simple.xml - xml файл для подписи
in_simple.xml_utf-8_sign_file.xml - xml файл с откреплённой подписью для файла in_simple.xml

Далее, пробую произвести проверку откреплённой подписи, как в примере, поставляемым с CryptoPro.Net SDK (simple.zip-
xml\vb\Verify.vb), с небольшими модификациями:
Код:

Public Shared Sub Main(ByVal args As String())
' Разбираем аргументы
If args.Length < 2 Then
Console.WriteLine("Xml.Verify <document> ...")
Return
End If

' Создаем новый XML документ в памяти.
Dim xmlDocument As XmlDocument = New XmlDocument()
Dim xmlSgn As XmlDocument = New XmlDocument()

' Сохраняем все пробельные символы, они важны при проверке
' подписи.
xmlDocument.PreserveWhitespace = True


xmlSgn.PreserveWhitespace = True
' Загружаем подписанный документ из файла.
xmlDocument.Load(args(0))
xmlSgn.Load(args(1))


' Ищем все node "Signature" и сохраняем их в объекте XmlNodeList
Dim nodeList As XmlNodeList = xmlSgn.GetElementsByTagName(
"Signature", SignedXml.XmlDsigNamespaceUrl)

Console.WriteLine("Найдено:{0} подпис(ей).", nodeList.Count)

' Проверяем все подписи.
For curSignature As Integer = 0 To nodeList.Count - 1
	' Создаем объект SignedXml для проверки подписи документа.
	Dim signedXml As SignedXml = New SignedXml(xmlDocument)

	' Загружаем узел с подписью.
	signedXml.LoadXml(nodeList(curSignature))

	' Проверяем подпись и выводим результат.

	Dim result As Boolean = signedXml.CheckSignature()

	' Выводим результат проверки подписи в консоль.
	If result Then
	    Console.WriteLine("XML подпись[{0}] верна.", curSignature + 1)
	Else
		Console.WriteLine("XML подпись[{0}] не верна.", curSignature + 1)
	End If
Next

End Sub


Однако, проверку не проходит, т.е.
в результате выполнения кода:
Код:
Dim result As Boolean = signedXml.CheckSignature()

Код:
result=False


Скажите пожалуйста, корректно ли проверять так откреплённую подпись
xml файла?
Если нет, то как правильно это делать?
Если да, то, может нужно другие SignatureMethod Algorithm
и(или) DigestMethod Algorithm использовать при формировании
xml файла с откреплённой подписью? Или же методы канонизации
Python и Net. Framework отличаются? Или что-то другое...











Offline Dmitrii F  
#2 Оставлено : 28 мая 2020 г. 21:01:04(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Вот здесь указано:
There is also a fourth kind of signature called an external detached signature which is when the data and signature are in separate XML documents. External detached signatures are not supported by the SignedXml class.
Offline Dmitrii F  
#3 Оставлено : 30 мая 2020 г. 17:11:31(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Есть предположение, что надо ещё
закрытый ключ отдавать в функцию
Код:
CheckSignature()


Но, если читать сертификат отдельно:
Код:
Dim cert As X509Certificate2 = New X509Certificate2()
            cert.Import(Path/to/cer.pem)

То он без закрытого ключа.

Есть ещё возможность, предварительно преобразовывать
сертификат к формату pkcs12, который содержит закрытый ключ:
Код:
openssl pkcs12 -export -in cer.pem -inkey cer.key -out сer.p12 -engine gost 


Но, он в Windows не импортируется, ни с помощью установщика,
ни из кода VB.
В последнем случае, выбрасывает исключение:
"Указан неправильный алгоритм"
Код:
Dim cert As X509Certificate2 = New X509Certificate2(path/to/cer.p12), "secretpassword")


Предполагаю, что, вероятно, надо задавать дополнительные параметры для
openssl, при создании pkcs12, как рекомендуют в этой теме

Т.е.
Цитата:
сертификат и ключ должны быть зашифрованы с помощью алгоритма ГОСТ 28147-89

И создавать pkcs12 нужно с дополнительными ключами:
-keypbe gost89 -certpbe gost89




Offline Dmitrii F  
#4 Оставлено : 30 мая 2020 г. 18:42:53(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Файл pkcs12, созданный с помощью команды:
Код:
openssl pkcs12 -export -in cer.pem -inkey cer.key -out сer.p12 -engine gost -keypbe gost89 -certpbe gost89


Не удаётся импортировать в Windows:
При помощи стандартного установщика - пароль введён неверно, хотя,
пароль, безусловно, верный

А в коде VB выкидывает исключение:
"Сетевой пароль указан неверно"
Offline Дмитрий Пичулин  
#5 Оставлено : 30 мая 2020 г. 19:49:29(UTC)
pd

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

Группы: Администраторы
Зарегистрирован: 16.09.2010(UTC)
Сообщений: 1,442
Откуда: КРИПТО-ПРО

Сказал(а) «Спасибо»: 31 раз
Поблагодарили: 412 раз в 306 постах
Автор: Dmitrii F Перейти к цитате
Есть предположение, что надо ещё
закрытый ключ отдавать в функцию
Код:
CheckSignature()


Закрытый ключ для проверки подписи точно не нужен, в этом смысл подписи, что она может быть проверена по открытому ключу в сертификате.

Знания в базе знаний, поддержка в техподдержке
Offline Dmitrii F  
#6 Оставлено : 30 мая 2020 г. 20:11:16(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Спасибо!

Кстати, если запустить пример (Simple\Xml\vb\SignDocument.vb),
то создаётся подпись - enveloped, правда, это только
работает с предварительно установленным сертификатом,
для которого есть закрытый ключ.
Такой документ проходит проверку
Код:
CheckSignature()
Offline Дмитрий Пичулин  
#7 Оставлено : 30 мая 2020 г. 23:02:34(UTC)
pd

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

Группы: Администраторы
Зарегистрирован: 16.09.2010(UTC)
Сообщений: 1,442
Откуда: КРИПТО-ПРО

Сказал(а) «Спасибо»: 31 раз
Поблагодарили: 412 раз в 306 постах
Автор: Dmitrii F Перейти к цитате
Спасибо!

Кстати, если запустить пример (Simple\Xml\vb\SignDocument.vb),
то создаётся подпись - enveloped, правда, это только
работает с предварительно установленным сертификатом,
для которого есть закрытый ключ.
Такой документ проходит проверку
Код:
CheckSignature()

Если речь про enveloped, то конечно это не подпись, а специфический формат данных, включающий данные зашифрованные в сторону сертификата, только владелец сертификата (закрытого ключа) может эти данные прочитать и удостовериться, что они получены из надёжного источника.

Конечно, для расшифрования нужен закрытый ключ, на основе которого будет выработан общий ключ шифрования.

Сформулируйте вопрос.
Знания в базе знаний, поддержка в техподдержке
Offline Dmitrii F  
#8 Оставлено : 31 мая 2020 г. 12:36:25(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Я попробовал создать откреплённую подпись средствами .Net без
enveloped и провести проверку, указанным в начале данной темы способом.
Такая откреплённая подпись проверку проходит.
Код VB для формирования откреплённой подписи xml документа, для
установленного ранее сертификата и закрытого ключа для него (модификация
примера Simple\Xml\vb\SignDocument.vb):

Код:
 Sub Main(args As String())
        Console.OutputEncoding = Encoding.UTF8
        Console.InputEncoding = Encoding.UTF8
        If args.Length < 2 Then
            Console.WriteLine("Xml.Verify <document> ...")
            Return
        End If
        'xml File to sign
        Dim xmlFileData As String = args(0)
        'signed xml file
        Dim xmlFileSigned As String = xmlFileData + "_SignedXml.xml"
        Try
            ' Find certificate in local store
            Dim store As X509Store = New X509Store("My", StoreLocation.CurrentUser)
            store.Open(OpenFlags.OpenExistingOnly Or OpenFlags.ReadOnly)
            Dim found As X509Certificate2Collection =
                store.Certificates.Find(X509FindType.FindBySubjectName,
                args(2), False)

            ' Check if one
            If found.Count = 0 Then
                Console.WriteLine("Certificate not found.")
                Return
            End If
            If found.Count > 1 Then
                Console.WriteLine("There was found more than one certificates.")
                Return
            End If
            Dim Certificate As X509Certificate2 = found(0)
            ' Open private key.
            Dim Key As AsymmetricAlgorithm = Certificate.PrivateKey
            
            Console.WriteLine("Signing: {0}", xmlFileData)

            'Create detach sign and save it to the file
            SignDetachedXML(xmlFileData, xmlFileSigned, Certificate, Key)

            Console.WriteLine("xml file was signed")
        Catch ex As Exception
            Console.WriteLine(ex.Message)
        End Try

    End Sub

    Sub SignDetachedXML(xmlData As String, xmlFileSignature As String, cer As X509Certificate2, Key As AsymmetricAlgorithm)
        'create a SignedXml object
        Dim xmlDocument As XmlDocument = New XmlDocument()
        xmlDocument.PreserveWhitespace = True

        xmlDocument.Load(xmlData)
        Dim SignedXML_ As SignedXml = New SignedXml(xmlDocument)

        'Add key to signed xml
        SignedXML_.SigningKey = Key

        'Add the reference to signed xml
        Dim ref As Reference = New Reference()
        ref.Uri = ""
        'Digest method
        ref.DigestMethod = CPSignedXml.XmlDsigGost3411_2012_256Url
        ' Transform for canonicalization
        Dim c14 As XmlDsigExcC14NWithCommentsTransform = New XmlDsigExcC14NWithCommentsTransform()
        ref.AddTransform(c14)
        SignedXML_.AddReference(ref)


        'Add keyInfo to signed xml
        Dim keyinfo_ As KeyInfo = New KeyInfo()
        'keyinfo_.AddClause(New RSAKeyValue(key))
        Dim keyInfoData As KeyInfoX509Data = New KeyInfoX509Data(cer)
        keyinfo_.AddClause(keyInfoData)
        SignedXML_.KeyInfo = keyinfo_

        'Set canonicalization as c14n#WithComments
        SignedXML_.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NWithCommentsTransformUrl
        'Set gost-2012-256 signing method
        SignedXML_.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url

        'Compute signature
        SignedXML_.ComputeSignature()

        'Create and save xml file with Signature
        Dim XmlSignatureFIle As XmlElement = SignedXML_.GetXml()

        Dim xmltw As XmlTextWriter = New XmlTextWriter(xmlFileSignature, New UTF8Encoding(False))
        XmlSignatureFIle.WriteTo(xmltw)
        xmltw.Close()


    End Sub


Такой пример работает, значит и приведённый в начале темы способ (вероятно) будет работать.
И, если функция
Код:
CheckSignature()

или её перегруженный вариант для CryptoPro.Net
не производит запросы на предмет валидности сертификата, к примеру, в УЦ,
то, получается, что не проверяет, потому-что:
Были допущены ошибки в процессе формирования сертификата

Или

Были допущены ошибки/неточности в процессе формирования откреплённой подписи для xml файла,
которых может быть несколько, по крайней мере:
1)неправильно рассчитываются значения digest и/или signature
2)лишние пробелы или пробелы не сохраняются
3)lxml.etree канонизация отличается от реализации .Net

Скажите пожалуйста, почему же приведённый в начале темы способ
формирования откреплённой подписи для xml файла не проходит валидацию
функцией
Код:
CheckSignature()

?

Отредактировано пользователем 31 мая 2020 г. 12:38:55(UTC)  | Причина: Не указана

Offline Dmitrii F  
#9 Оставлено : 31 мая 2020 г. 16:32:30(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Извините, что не написал, ранее, вероятно, это важно.
Сертификаты, которые создаются в openssl по алгоритму gost2012_256 (в начале темы),
они self-signed.
Offline Dmitrii F  
#10 Оставлено : 1 июня 2020 г. 1:02:18(UTC)
Dmitrii F

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Проверку в openssl, значение signature проходит:

Код:
openssl dgst -md_gost12_256 -pverify privatekey.key \
        -signature signature.sign \
        input_file
#privatekey.pem - закрытый ключ
#signature.sign - рассчитанное ранее значение сигнатуры для проверки
#input_file - файл, для которого ранее вычислялось signature



Ещё заметил, что у меня, вероятно, есть ошибка в формировании значения signature,
т.к. для расчёта signature, использую предварительно рассчитанный digest.
Т.е. сейчас:
Код:
openssl dgst -sign private_key -binary -md_gost12_256 digest_value 
#private_key - ключ, digest_value - полученное ранее значение digest


А, вероятно, нужно, так:
Код:
openssl dgst -sign private_key -binary -md_gost12_256 canonicalizated.xml 
#private_key - закрытый ключ, canonicalizated.xml  - xml файл, для которого вычисляется signature, в канонической форме


Но, всё равно, проверку функцией
Код:
CheckSignature()

не проходит.

Отредактировано пользователем 1 июня 2020 г. 1:03:41(UTC)  | Причина: Дополнение

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