SHA1 + RSA-帮助在C ++中使用Botan

时间:2019-06-21 18:06:42

标签: c++ encryption sha botan

我正在为阿根廷的“电子发票”开发C ++的Web服务客户端。 Web服务客户端和xml处理不是问题,但是加密部分使您有些头疼(我在本主题中是很新的东西)。

我正在阅读Botan文档,发现了一个与我需要的示例有些相似的示例,但是我很难适应它。

我需要使用证书在SHA1 + RSA中加密XML,并在Base64中对结果进行编码。

不幸的是,官方文档提供了多种语言的示例,但C ++并不是其中之一,我以php示例为起点,用C ++创建我的PoC代码。

确切的问题是这个。

我有这个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
    );

其中CERTPRIVATEKEY是公钥和私钥,PASSPHRASE是一个空字符串,文件TRA.xml包含上面提供的XML示例。

您可以从此链接下载公钥和私钥 Example Certificates

C ++中的Botan示例

#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
}

我需要使用证书在SHA1 + RSA中加密XML,并在Base64中对结果进行编码。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

关于您的主要问题,我有些困惑。猜猜你不得不提到它更明显。但是,正如我注意到的那样,问题在于如何使用公共RSA密钥和SHA-1哈希函数进行加密! (我说得对吗?)

因此,在那种情况下,我想说的是,您在加密器/解密器对象中​​看到的EME1(SHA-256)不是用于加密的批量加密算法和哈希函数。它们是填充算法!

在Botan中,有 tls_channel tls_callbacks 可以处理双方之间的加密和解密的整个过程。进一步查看它们。

如果Botan不是强制性的,我建议您在evp.h文件中使用 Openssl ,函数EVP_SealInit可以通过用{{1 }}输入。有关更多信息,check this link