Подпись не валидного XML

Коллеги добрый день!

Стоит задача подписать XML от портала ESF с помощью libkalkancryptwr-64.so.

С помощью метода SignXML это сделать не возможно т.к. у XML документа не валидный namespace.

Пытаюсь получить нужные данные и собрать итоговый XML документ руками, но не могу найти с помощью каких функций и флагов эти данные получить.

В качестве эксперимента подписываю 1 тестовым ключом. SignXML дает такой итоговый документ:

<?xml version="1.0" encoding="UTF-8"?>
<root>1<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="1">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:pkigovkz:xmlsec:algorithms:gostr34102015-gostr34112015-512"/>
<ds:Reference URI="">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:pkigovkz:xmlsec:algorithms:gostr34112015-512"/>
<ds:DigestValue>3XKYmj8lUmoZUTAkMpHXp/myCokixrkijYGZ91UqX5d99mTKGuNfDlAt/0yMdstP
8Z5yki1c6CMGNezd0Ab2eQ==</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
  
 
 
 <ds:SignatureValue>ppA83sxU0t7AyIU+4203wDIXJG4ez48Rrj0hgK36nrh5o+DXL506wbwm8pOJsxLY
ALG/t5iyq1GaIQPjL4IVZ5jnrzUuEnna6Z6LpeeaoGt1OqjzKjhdkiZaFqGFZ8ve
JsUDynHKOKOhAnUm6jVD2ztV1zX2BRpjkHG2zCyNuwo=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIENjCCA56gAwIBAgIUEUcodYLfm7RxDkYYBKzUm4i/RcQwDgYKKoMOAwoBAQID
AgUAMF0xTjBMBgNVBAMMRdKw0JvQotCi0KvSmiDQmtCj05jQm9CQ0J3QlNCr0KDQ
o9Co0Ksg0J7QoNCi0JDQm9Cr0pogKEdPU1QpIFRFU1QgMjAyMjELMAkGA1UEBhMC
S1owHhcNMjMxMTA5MTAxODQwWhcNMjQxMTA4MTAxODQwWjB5MR4wHAYDVQQDDBXQ
otCV0KHQotCe0JIg0KLQldCh0KIxFTATBgNVBAQMDNCi0JXQodCi0J7QkjEYMBYG
A1UEBRMPSUlOMTIzNDU2Nzg5MDExMQswCQYDVQQGEwJLWjEZMBcGA1UEKgwQ0KLQ
ldCh0KLQntCS0JjQpzCBrDAjBgkqgw4DCgEBAgIwFgYKKoMOAwoBAQICAQYIKoMO
AwoBAwMDgYQABIGA2vzSnxC/K74V0b9QzJ/r2mM9GxhbOosYKI0SBCnAo2IbeA5H
Kzzhlt5PhEeGEdTN4wr9bW+xR4vxEBVqDniAYRR6unCfzOmRy7nMo5yA4JPwu872
4OZlwe2CEBsmBytAyReCth6RZMyeAzTD/S6ayoBmKfVAlCFB9BX5cEJVV2qjggHG
MIIBwjA4BgNVHSAEMTAvMC0GBiqDDgMDAjAjMCEGCCsGAQUFBwIBFhVodHRwOi8v
cGtpLmdvdi5rei9jcHMwdwYIKwYBBQUHAQEEazBpMCgGCCsGAQUFBzABhhxodHRw
Oi8vdGVzdC5wa2kuZ292Lmt6L29jc3AvMD0GCCsGAQUFBzAChjFodHRwOi8vdGVz
dC5wa2kuZ292Lmt6L2NlcnQvbmNhX2dvc3QyMDIyX3Rlc3QuY2VyMEEGA1UdHwQ6
MDgwNqA0oDKGMGh0dHA6Ly90ZXN0LnBraS5nb3Yua3ovY3JsL25jYV9nb3N0MjAy
Ml90ZXN0LmNybDBDBgNVHS4EPDA6MDigNqA0hjJodHRwOi8vdGVzdC5wa2kuZ292
Lmt6L2NybC9uY2FfZ29zdDIwMjJfZF90ZXN0LmNybDAdBgNVHSUEFjAUBggrBgEF
BQcDBAYIKoMOAwMEAQEwDgYDVR0PAQH/BAQDAgPIMB0GA1UdDgQWBBSBRyh1gt+b
tHEORhgErNSbiL9FxDAfBgNVHSMEGDAWgBT60ksbo6DJYf4cqFA+aqK7RQ24ozAW
BgYqgw4DAwUEDDAKBggqgw4DAwUBATAOBgoqgw4DCgEBAgMCBQADgYEAac/t5Kbx
JSmX7Mh1Wzlqm83UuY6iGn2TrnDTTN0n6oFuNBT9lFyvX6HwwXF7K2cV0C/D/bd2
vvTrLVTdild6yqX+0rf4mHtLfZAo2WYt+9LeybWppE2ZGkaxXCS2di+bZwyPoV2N
iA0QJRgQAtuCDy7LY+pySBNUtvBdUXgYcxM=</ds:X509Certificate>
2024-04-24T12:05:27.425516680Z </ds:X509Data>
2024-04-24T12:05:27.425517721Z </ds:KeyInfo>
2024-04-24T12:05:27.425518430Z </ds:Signature></root>

Как получить значения полей ds:DigestValue и ds:SignatureValue не удается разобраться. Нужна ваша помощь!

Добрый день!
DigestValue - это хэш от всей XML-структуры, которую подписываете.
SignatureValue - это подписание хэша от блока SignedInfo.

Подскажите, что за такой невалидный namespace Вы пытаетесь подписать? Пришлите пример

Здравствуйте, Данил

Вот пример документа, убрал часть полей что-бы пример был покороче:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<esf:invoiceContainer xmlns:esf="esf">
    <invoiceSet>
        <v2:invoice xmlns:a="abstractInvoice.esf" xmlns:v2="v2.esf">
            <date>03.10.2017</date>
            <invoiceType>ORDINARY_INVOICE</invoiceType>
            <num>2038556421124573223</num>
            <operatorFullname>Иванов Иван Иванович</operatorFullname>
            <turnoverDate>02.10.2017</turnoverDate>
            <customers>
            </customers>
            <deliveryDocDate>19.09.2017</deliveryDocDate>
            <deliveryDocNum>555</deliveryDocNum>
            <deliveryTerm>
            </deliveryTerm>
            <productSet>
            </productSet>
            <sellers>
            </sellers>
        </v2:invoice>
    </invoiceSet>
</esf:invoiceContainer>

Вывод при попытке подписания:

C14N error : Relative namespace UR is invalid here : (null)
C14N error : Internal error : checking for relative namespaces
C14N error : Internal error : processing docs children list
signXML error: KCR_XMLSETSIGNERROR

Здравствуйте, Данил.

Подскажите какой алгоритм хеширования и какие флаги должны использоваться для получения хеша всей XML-структуры для DigestValue?

В качестве эксперимента подписал функцией SignXML документ

<root>1</root>

Получил поле DigestValue такое:

<ds:DigestValue>3XKYmj8lUmoZUTAkMpHXp/myCokixrkijYGZ91UqX5d99mTKGuNfDlAt/0yMdstP8Z5yki1c6CMGNezd0Ab2eQ==</ds:DigestValue>

При получении хэша от этого же документа функцией HashData получаю следующие значения:

Алгоритм Gost34311_95

2BRjbvCVAHXNnmOQOUoN3Gl4ByoTxFoLnlxitnJVK8Y=

Алгоритм sha256

fzNj6kXUBFtw5pJRkyP6BauVRsicrZzbaXmXuHH1rko=

Не удается получить хэш аналогичный полю DigestValue

Здравствуйте!

Это зависит от ключа, которым производится подпись.
Либо SHA256 - KC_HASH_SHA256, либо Гост34.311 95 - KC_HASH_GOST95, либо Гост Р 34.11 2015 - KC_HASH_GOST15_512
Флаги имеются в описании к библиотеке.

Здравствуйте, Данил!

Снова нужна ваша помощь.

Подписываю хэш от блока SignedInfo с помощью SignData с флагами KC_SIGN_DRAFT | KC_IN_BASE64 | KC_OUT_BASE64.

Пытаюсь проверить подпись с помощью VerifyData, в inData передаю хэш, в inSign подпись. С флагами из примера в документации KC_SIGN_DRAFT | KC_IN2_BASE64 получаю ошибку KCR_INVALID_DIGEST_LEN. Никаких манипуляций с хэшом, между получением, подписью и проверкой не происходит. Поиском по форуму ничего по этой ошибке не нашел. Подскажите в чем может быть проблема?

Пытался проверить подпись с другим набором флагов KC_SIGN_DRAFT | KC_IN_BASE64 | KC_OUT_BASE64 получил не документированную ошибку 2147934331.

Добрый день!
Для проверки DraftSign необходимо передавать не хэш, а сами подписанные данные.