I'm developing a WebService client in C++ for "Electronic Invoice" in Argentina. The webservice client and the xml treatment is not a problem but the cryptographic part give some headache (I'm quite new in this topic).
I'm reading the Botan documentation and found an example somewhat similar to what I need but I'm having difficulties adapting it.
I need to encrypt the XML in SHA1+RSA using the certificates and encode the result in Base64.
The official documentation provide examples in many languages unfortunately C++ is not one of them, I use the php example as start point to create my PoC code in C++.
The exact problem is this.
I have this XML example:
<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>
this XML became in this Base64 string
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==
using this PHP function
$STATUS=openssl_pkcs7_sign("TRA.xml", "TRA.tmp", "file://".CERT,
array("file://".PRIVATEKEY, PASSPHRASE),
array(),
!PKCS7_DETACHED
);
Where CERT
and PRIVATEKEY
are the public and private keys, PASSPHRASE
is an empty string and the file TRA.xml contains the XML example provided above.
You can download the public and private key from this link Example Certificates
Botan Example in 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
}
I need to encrypt the XML in SHA1+RSA using the certificates and encode the result in Base64. Any help will be very appreciated.