Почему OpenSSL в C ++ производит другой вывод, чем командная строка - PullRequest
0 голосов
/ 06 июня 2018

Я посмотрел несколько примеров кода для OpenSSL, чтобы хэшировать некоторый контент, используя SHA256, и подписать его с помощью ключа RSA - мне также нужно закодировать полученную строку в шестнадцатеричный формат.Я использовал этот источник для справки: https://gist.github.com/irbull/08339ddcd5686f509e9826964b17bb59

Это метод более высокого уровня, который принимает сообщение

std::string Sign(const std::string& key, const 
std::string& message, bool bPrivate)
{


    RSA* rsa = CreateRSAFromString(key, isPrivate);

    if(!rsa)
    {
        // Print errors here...
        return "";
    }

    unsigned char* outMessage;           
    size_t outMessageLength;

    RSASign(rsa, 
            (unsigned char*) message.c_str(), 
            message.length(), 
            &outMessage, 
            &outMessageLength);


    std::string myString(reinterpret_cast<const char*>(outMessage), outMessageLength);

    // Convert the string to hex
    std::string hexOutMessage = ToHex(myString);
    free(outMessage);
    return hexOutMessage;
}

Фактический метод знака RSA выглядит довольно простым.Насколько я понимаю, это должно сначала хэшировать содержимое с использованием SHA256, а затем переходит к шифрованию с помощью RSA.

bool RSASign(RSA* rsa,
        const unsigned char* msg,
        size_t msgLength,
        unsigned char** outMsg,
        size_t* outMsgLength)
{ 
EVP_MD_CTX* context = EVP_MD_CTX_create();

EVP_PKEY* privateKey = EVP_PKEY_new(); 
EVP_PKEY_assign_RSA(privateKey, rsa);  


if(EVP_DigestSignInit(context, NULL, EVP_sha256(), NULL, privateKey) <= 0)
{
    return false;   // Initialize the digest failed
}

if (EVP_DigestSignUpdate(context, msg, msgLength) <= 0) 
{
    return false;   // Adding the message failed
}

if (EVP_DigestSignFinal(context, NULL, outMsgLength) <= 0)
{
    return false;   // Finalization failed, cannot create signature
}

*outMsg = (unsigned char*)malloc(*outMsgLength);
if(EVP_DigestSignFinal(context, *outMsg, outMsgLength) <= 0)
{
    return false;   // Error creating encoded message
}
EVP_MD_CTX_destroy(context);
// End of context

return true;
}

Для полноты, именно здесь происходит фактическое создание объекта RSA:

RSA* CreateRSAFromString(const std::string& key, bool isPrivate)
{
RSA* rsa = NULL;
BIO* keybio = BIO_new_mem_buf((void*)key.c_str(), -1);  

if(!keybio)
{
    return NULL;
}

rsa = isPrivate ? PEM_read_bio_RSAPrivateKey(keybio, NULL, NULL, NULL):
                  PEM_read_bio_RSA_PUBKEY(keybio, NULL,NULL, NULL);
return rsa;
}

Я хочу проверить правильность моего процесса, потому что при выводе шестнадцатеричного результата я получаю совершенно разные результаты между командной строкой и C ++.В частности, эквивалентная команда, которую я пытаюсь выполнить, выглядит следующим образом:

dgst -sha256 -sign certifcate.pem -out signed.txt inputFile.json

Если я могу убедиться, что сторона OpenSSL верна, то я, вероятно, могу сделать вывод, что это мое преобразование в гекс, чтовносит несоответствие.На стороне OpenSSL ничего не выводилось ни ошибок, ни сбоев.

...