SHA1+RSA — помощь в использовании Botan на C++

Я разрабатываю клиент WebService на С++ для «Электронного счета-фактуры» в Аргентине. Клиент веб-сервиса и обработка xml не являются проблемой, но криптографическая часть вызывает некоторую головную боль (я новичок в этой теме).

Я читаю документацию Botan и нашел пример, несколько похожий на то, что мне нужно, но у меня возникают трудности с его адаптацией.

Мне нужно зашифровать XML в SHA1+RSA с помощью сертификатов и закодировать результат в Base64.

Официальная документация содержит примеры на многих языках, к сожалению, C++ не является одним из них, я использую пример php в качестве отправной точки для создания своего кода PoC на C++.

Точная проблема вот в чем.

У меня есть этот пример XML:

<loginTicketRequest version="1.0"><header><uniqueId>1560949868</uniqueId><generationTime>2019-06-19T10:10:08-03:00</generationTime><expirationTime>2019-06-19T10:12:08-03:00</expirationTime></header><service>wsfe</service></loginTicketRequest>

этот XML превратился в эту строку Base64

MIIHDgYJKoZIhvcNAQcCoIIG/zCCBvsCAQExDzANBglghkgBZQMEAgEFADCCAS8G
CSqGSIb3DQEHAaCCASAEggEcPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0i
VVRGLTgiPz4NCjxsb2dpblRpY2tldFJlcXVlc3QgdmVyc2lvbj0iMS4wIj48aGVh
ZGVyPjx1bmlxdWVJZD4xNTYwOTQ5ODY4PC91bmlxdWVJZD48Z2VuZXJhdGlvblRp
bWU+MjAxOS0wNi0xOVQxMDoxMDowOC0wMzowMDwvZ2VuZXJhdGlvblRpbWU+PGV4
cGlyYXRpb25UaW1lPjIwMTktMDYtMTlUMTA6MTI6MDgtMDM6MDA8L2V4cGlyYXRp
b25UaW1lPjwvaGVhZGVyPjxzZXJ2aWNlPndzZmU8L3NlcnZpY2U+PC9sb2dpblRp
Y2tldFJlcXVlc3Q+DQqgggPMMIIDyDCCArCgAwIBAgIISL4VMzAJIDswDQYJKoZI
hvcNAQEFBQAwQzElMCMGA1UEAwwcQUZJUCBUZXN0aW5nIENvbXB1dGFkb3JlcyBD
QTENMAsGA1UECgwEQUZJUDELMAkGA1UEBhMCQVIwHhcNMTQxMDE2MTk0NTA2WhcN
MTcwNzEyMTk0NTA2WjBmMRkwFwYDVQQDDBBNYXJpYW5vIFJlaW5nYXJ0MRkwFwYD
VQQFExBDVUlUIDIwMjY3NTY1MzkzMSEwHwYDVQQKDBhQeUFmaXBXcy1TaXN0ZW1h
cyBBZ2lsZXMxCzAJBgNVBAYTAkFSMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQCa+TDQaSgL1/wcMzFJXi1ipc2VurFOx4LlP13pIrC0hX2xP+I+qNeD2vZlaiA0
bMAZfx6w/+KjOPsJaQXre+TC6NU7Ed7FV6GZO6a2ZM/KjkoJSJIG/aVn+jljOkkl
2ANiTghi9tT3hPK1k6KQz6X2uBHaInKMrvi2Cj9/Tvi6UQIDAQABo4IBHzCCARsw
DAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFJ61KivCQwKv
/FnE6OJhBgz4nzjsMB8GA1UdIwQYMBaAFER07rScJt9W4cEN61cLkBk2PZYBMIG6
BgNVHSAEgbIwga8wgawGDisGAQQBgbtjAQIBAgEBMIGZMIGWBggrBgEFBQcCAjCB
iR6BhgBDAGUAcgB0AGkAZgBpAGMAYQBkAG8AIABwAGEAcgBhACAAYwBvAG0AcAB1
AHQAYQBkAG8AcgBlAHMAIABzAG8AbABvACAAdgBhAGwAaQBkAG8AIABlAG4AIABl
AG4AdABvAHIAbgBvAHMAIABkAGUAIABkAGUAcwBhAHIAcgBvAGwAbABvMA0GCSqG
SIb3DQEBBQUAA4IBAQCM/PmA6htlY/X8XK98XOtQxjOaLt5MgFdGiwyop13Xyh3n
c9ak4KFP6qbz6gKzCelkYoPgFLreP+lvL62EYrNaLacNLZUbko7wZotjRRxZo0+f
OkjJMIafgM5mycdVvcI1uzIKPWba5F5w8NawcL8bloSqDWX1dJRwvhs2hmcN3iIf
aYosbVUI/DMLys1xFqCMSBrTX4xtfL82TOg+mSVaRW37aED8ta7jTcBTn+001nos
c/1rXrB0qBQa7EKD7VJKSLkn4RV/HwO8R1POVexyrk7TzNeamcQMIKjkhHzXSsOb
BROqptCxUDh4QUdLQNRtwsJClufr6Bgidg37JK+4MYIB4DCCAdwCAQEwTzBDMSUw
IwYDVQQDDBxBRklQIFRlc3RpbmcgQ29tcHV0YWRvcmVzIENBMQ0wCwYDVQQKDARB
RklQMQswCQYDVQQGEwJBUgIISL4VMzAJIDswDQYJYIZIAWUDBAIBBQCggeQwGAYJ
KoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwNjE5MTMx
MTA4WjAvBgkqhkiG9w0BCQQxIgQgPhDZEOopRNlv7JVKSyLZ2AWdNb81O6zm3hgM
BADUI34weQYJKoZIhvcNAQkPMWwwajALBglghkgBZQMEASowCwYJYIZIAWUDBAEW
MAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZI
hvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAE
gYAaqEV7X2WqmODhoqV64aLmM1mkUuVsGxgBDc09IRwUtD6wQAoMd87iIVeQ0n2X
qHHjmAz8QLp5tCApSPLjdaXbzufJ6vfOhpuHzu2QuOZh7AM9g8+zLubcs/+aRGC8
RUXoVaHajVOeHN4iR5pIJ3n2zuIWgowyK1sH3Q33i0A+MQ==

используя эту функцию PHP

  $STATUS=openssl_pkcs7_sign("TRA.xml", "TRA.tmp", "file://".CERT,
    array("file://".PRIVATEKEY, PASSPHRASE),
    array(),
    !PKCS7_DETACHED
    );

Где CERT и PRIVATEKEY — открытый и закрытый ключи, PASSPHRASE — пустая строка, а файл TRA.xml содержит приведенный выше пример XML.

Вы можете скачать открытый и закрытый ключ по этой ссылке Пример Сертификаты

Пример Botan на C++

#include <botan/pkcs8.h>
#include <botan/hex.h>
#include <botan/pk_keys.h>
#include <botan/pubkey.h>
#include <botan/auto_rng.h>
#include <botan/rng.h>
#include <iostream>

int main (intargc,char*argv[])
{
    if(argc!=2)
        return1;
    std::string plaintext("Your great-grandfather gave this watch to your granddad for good luck. Unfortunately, Dane's luck wasn't as good as his old man's.");

    std::vector<uint8_t> pt(plaintext.data(),plaintext.data()+plaintext.length());
    std::unique_ptr<Botan::RandomNumberGenerator> rng(newBotan::AutoSeeded_RNG);

    //load keypair

    std::unique_ptr<Botan::Private_Key> kp(Botan::PKCS8::load_key(argv[1],*rng.get()));
    //encrypt with pk
    Botan::PK_Encryptor_EME enc(*kp,*rng.get(), "EME1(SHA-256)");
    std::vector<uint8_t> ct = enc.encrypt(pt,*rng.get());
    //decrypt with sk
    Botan::PK_Decryptor_EME dec(*kp,*rng.get(), "EME1(SHA-256)");
    std::cout << std::endl << "enc: " << Botan::hex_encode(ct) << std::endl << "dec: "<< Botan::hex_encode(dec.decrypt(ct));

    return 0; //Edited :D, Thanks jww
}

Мне нужно зашифровать XML в SHA1+RSA с помощью сертификатов и закодировать результат в Base64. Любая помощь будет очень признательна.


person Trungus    schedule 21.06.2019    source источник
comment
+1 для Ботана. Я думаю, что это хороший выбор для этой проблемы. return0; не будет компилироваться. Также см. Как создать минимальный, полный и проверяемый пример.   -  person jww    schedule 21.06.2019
comment
возврат0; была опечатка при создании поста. Тем не менее я понятия не имею, как создать пример, читающий сертификаты X509, и подписать им XML с помощью SHA1+RSA. Спасибо   -  person Trungus    schedule 24.06.2019


Ответы (1)


Я немного запутался в вашем основном вопросе. Думаю, вы должны упомянуть это более очевидно. Но, как я заметил, проблема заключается в том, как зашифровать с помощью открытого ключа RSA и SHA-1 хеш-функции! (Я прав?)

Так что в этом случае я бы сказал, что EME1(SHA-256), которые вы можете видеть в объектах шифратора/дешифратора, не являются алгоритмом массового шифрования и хеш-функцией, используемой для шифрования. Это алгоритмы заполнения!

В Botan есть tls_channel и tls_callbacks, которые обрабатывают весь процесс шифрования и дешифрования между двумя сторонами. Взгляните на них дальше.

Также, если Botan не является обязательным, я предлагаю вам использовать Openssl в evp.h файле, функция EVP_SealInit может помочь вам, позволив выбрать желаемый алгоритм с const EVP_CIPHER *type вводом. Для получения дополнительной информации перейдите по этой ссылке

person AmirH.    schedule 19.08.2019