Я посмотрел несколько примеров кода для 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 ничего не выводилось ни ошибок, ни сбоев.