gpt4 book ai didi

c++ - 尝试在 OpenSSL 中使用 EVP 函数时出现段错误

转载 作者:行者123 更新时间:2023-11-30 03:55:58 25 4
gpt4 key购买 nike

我正在尝试使用 RSA 及其高级信封函数通过 OpenSSL 进行公共(public)加密。但是,我似乎无法理解它们,并且遇到了段错误。我项目中的这段压缩代码重现了这个问题:

#include <iostream>
#include <string>

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/rand.h>

int main()
{
EVP_CIPHER_CTX *rsaCtx;
rsaCtx = new EVP_CIPHER_CTX;

unsigned char *ek;
size_t ekl;
unsigned char *iv;
size_t ivl;

EVP_PKEY *keypair;
keypair = NULL;

EVP_CIPHER_CTX_init(rsaCtx);

EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048);
EVP_PKEY_keygen(ctx, &keypair);
EVP_PKEY_CTX_free(ctx);

ek = new unsigned char[EVP_PKEY_size(keypair)];
iv = new unsigned char[EVP_MAX_IV_LENGTH];
ivl = EVP_MAX_IV_LENGTH;

std::string cipherText;
std::string plainText = "A STRING";
size_t encMsgLen = 0;
size_t blockLen = 0;

EVP_SealInit(rsaCtx, EVP_aes_256_cbc(), &ek, (int*)ekl, iv, &keypair, 1);
EVP_SealUpdate(rsaCtx, (unsigned char*)cipherText.c_str() + encMsgLen, (int*)&blockLen, (const unsigned char*)plainText.c_str(), (int)plainText.size() + 1);
encMsgLen += blockLen;
EVP_SealFinal(rsaCtx, (unsigned char*)cipherText.c_str() + encMsgLen, (int*)&blockLen);
encMsgLen += blockLen;
EVP_CIPHER_CTX_cleanup(rsaCtx);

EVP_PKEY_free(keypair);
delete[] ek;
delete[] iv;
delete rsaCtx;

std::cout << cipherText;

return 0;
}

我在行 EVP_SealInit(rsaCtx, EVP_aes_256_cbc(), &ek, (int*)ekl, iv, &keypair, 1);

我做错了什么?

最佳答案

eklsize_t ,并且您正在将其转换为 (int*) .

docs for EVP_SealInit 说:

The actual size of each encrypted secret key is written to the array ekl.

您只是传递一个键,因此传递单个整数的地址就足够了,但您应该传递该整数的地址,例如:

EVP_SealInit(rsaCtx, EVP_aes_256_cbc(), &ek, reinterpret_cast<int*>(&ekl), iv, &keypair, 1);

或者,只需声明 ekl作为int首先,你可以避免强制转换:

int ekl;
//...
EVP_SealInit(rsaCtx, EVP_aes_256_cbc(), &ek, &ekl, iv, &keypair, 1);

我很惊讶你的编译器没有警告你使用未初始化的局部变量。

更新:除了段错误之外,这段代码还有一些问题。

您正在从一个空的 std::string 传递缓冲区( cipherText ) 变成 EVP_SealUpdateEVP_SealFinal .这通常不会起作用,如果缓冲区中没有足够的空间,可能会崩溃或损坏内存。

您应该为输出声明一个大小合适的缓冲区,可能是std::vector<unsigned char> cipherText(bufferSize);。 , 并传递 &cipherText[0]获取指向第一个元素的指针。

cipherText中的数据不是人类可读的字符串,它是二进制数据,并且 std::cout不适合展示。

一些更一般的注释:

  • 避免在 C++ 中进行 C 风格的强制转换,并尽可能编写代码以便您根本不需要强制转换(例如,将整数声明为 int 而不是 size_t,如果这是 API 所期望的)。
  • 使用 new 避免显式内存管理和 delete你可以在哪里,例如通过使用 std::vector<unsigned char>用于缓冲区。

我建议再次查看这些函数的文档,或者网络上的其他一些使用它们的示例。此外,编写一些执行解密步骤的代码,以便您可以测试纯文本是否正确往返。

关于c++ - 尝试在 OpenSSL 中使用 EVP 函数时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28787834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com