Расчет хэш-суммы по ГОСТ
Нужно посчитать хэш значение по алгоритму ГОСТ 34.11 Есть документация где рассчитан пример:
<ds:Reference URI="#id-9a89bcea-eb0d-41f2-a8e8-405ad5ea0d62">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
<ds:DigestValue>STvOHkqaWjQbVCkB7mnG++RLLdGmjryqTqS+BcZx4Cg=</ds:DigestValue>
</ds:Reference>
Область документа, на которую ссылается:
<a:To wsu:Id="id-9a89bcea-eb0d-41f2-a8e8-405ad5ea0d62" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">https://ips.test.egisz.rosminzdrav.ru/57234d87b0838</a:To>
Я так и не понял, по какому алгоритму нужно получить хэш-сумму(34.11-2012 или 34.11-1994) Вот код для 34.11-2012(библиотека pygost: https://github.com/ilyaTT/pygost_0_15/tree/master):
from lxml import etree
from pygost.gost3411_12 import GOST341112
import base64
data = '''<a:To wsu:Id="id-9a89bcea-eb0d-41f2-a8e8-405ad5ea0d62" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:a="http://www.w3.org/2005/08/addressing">https://ips.test.egisz.rosminzdrav.ru/57234d87b0838</a:To>'''
parser = etree.XMLParser(remove_blank_text=True)
xml_tree = etree.fromstring(data.encode("utf-8"), parser)
canonical_xml = etree.tostring(xml_tree, method="c14n", exclusive=True).decode("utf-8")
canonical_base64 = base64.b64encode(canonical_xml.encode("utf-8")).decode("utf-8")
data_bytes = canonical_base64.encode("utf-8")[::-1]
# Хэшируем
gost_hash = GOST341112(digest_size=256)
gost_hash.update(data_bytes)
signature_hash = gost_hash.digest()[::-1]
# Хэш в шестнадцатеричной строке
hex_string = signature_hash.hex()
print("HEX:", hex_string)
new_value = base64.b64encode(signature_hash).decode()
print("BASE64:", new_value)
Хэш-сумма, получаемая в программе, не совпадает с той что в образце.
Реализация для ГОСТ 34.11-1994:
from lxml import etree
from pygost.gost3411_94 import GOST341194
import base64
# Исходный XML-документ
xml_data = '''<a:To wsu:Id="id-9a89bcea-eb0d-41f2-a8e8-405ad5ea0d62" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">https://ips.test.egisz.rosminzdrav.ru/57234d87b0838</a:To>'''
root = etree.fromstring(xml_data)
# Канонизируем (c14n)
data_to_hash = etree.tostring(root, method="c14n", exclusive=True, with_comments=False)
print(type(data_to_hash))
print(data_to_hash)
# Вычисляем хэш (ГОСТ Р 34.11-94)
gost_hash = GOST341194(data_to_hash)
digest_value = gost_hash.digest()
digest_base64 = base64.b64encode(digest_value).decode()
print("DigestValue:", digest_base64)
Получил хэш: "ost9NriBuOVw2DKHUiKThCpIVkk2HITA0v6cMWv16mU=" А должно получится: "STvOHkqaWjQbVCkB7mnG++RLLdGmjryqTqS+BcZx4Cg="