Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenSSL EVP_DigestSignFinal segfault_C++_C_Cryptography_Openssl_Sign - Fatal编程技术网

C++ OpenSSL EVP_DigestSignFinal segfault

C++ OpenSSL EVP_DigestSignFinal segfault,c++,c,cryptography,openssl,sign,C++,C,Cryptography,Openssl,Sign,我正在尝试使用OpenSSL C api对消息进行签名。在调用EVP\u DigestSignFinal的过程中,由于EXC\u BAD\u ACCESS导致以下代码段出现故障。我使用的是OpenSSL 1.0.1g。我试着从较新的DigestSign*函数切换到较旧的Sign*函数,但仍然存在故障 private_-key通过从PEM文件加载的RSA密钥设置EVP_-PKEY_-set1_-RSA。对EVP_DigestSignFinal的第一次调用使用签名算法的签名的最大可能长度填充s_le

我正在尝试使用OpenSSL C api对消息进行签名。在调用
EVP\u DigestSignFinal
的过程中,由于
EXC\u BAD\u ACCESS
导致以下代码段出现故障。我使用的是OpenSSL 1.0.1g。我试着从较新的
DigestSign*
函数切换到较旧的
Sign*
函数,但仍然存在故障

private_-key
通过从PEM文件加载的RSA密钥设置
EVP_-PKEY_-set1_-RSA
。对
EVP_DigestSignFinal
的第一次调用使用签名算法的签名的最大可能长度填充
s_len
,因此
signature
不够大不应该成为问题,第二次调用写入签名缓冲区并使用签名长度填充
s_len

如果能得到任何帮助,我将不胜感激

vector<unsigned char> rsa_sha512_sign(
        const vector<unsigned char>& document, 
        shared_ptr<EVP_PKEY> private_key) {
    EVP_MD_CTX* md;
    if (!(md = EVP_MD_CTX_create())) {
        throw runtime_error("Error initializing ENV_MD_CTX.");
    }

    if (EVP_DigestSignInit(md, NULL, EVP_sha512(), NULL, private_key.get()) 
            != 1) {
        throw runtime_error("Error in EVP_DigestSignInit.");
    }

    if (EVP_DigestSignUpdate(md, document.data(), document.size()) != 1) {
        throw runtime_error("Error computing hash on document.");
    }
    size_t s_len;
    if (EVP_DigestSignFinal(md, NULL, &s_len) != 1) { // Segfault here
        throw runtime_error("Error determining maximum signature size.");
    }

    vector<unsigned char> signature(s_len);
    if (EVP_DigestSignFinal(md, signature.data(), &s_len) != 1) { // or here (or both)
        throw runtime_error("Error signing document.");
    }
    signature.resize(s_len);
    EVP_MD_CTX_destroy(md);
    return move(signature);
}
向量rsa\u-sha512\u符号(
常量向量和文档,
共享(私钥){
执行副总裁MD CTX*MD;
如果(!(md=EVP\U md\U CTX\U create()){
抛出运行时错误(“初始化ENV_MD_CTX时出错”);
}
if(EVP_DigestSignInit(md,NULL,EVP_sha512(),NULL,private_key.get())
!= 1) {
抛出运行时错误(“EVP\U DigestSignInit中的错误”);
}
如果(EVP_DigestSignUpdate(md,document.data(),document.size())!=1){
抛出运行时_错误(“在文档上计算哈希时出错”);
}
尺寸;
如果(EVP_DigestSignFinal(md,NULL,&s_len)!=1){//Segfault在此
抛出运行时_错误(“确定最大签名大小的错误”);
}
矢量签名(s_len);
if(EVP_DigestSignFinal(md,signature.data(),&s_len)!=1){//或此处(或两者)
抛出运行时_错误(“错误签名文档”);
}
签名。调整大小(s_len);
执行副总裁MD CTX销毁(MD);
回迁(签名);
}

问题可能在于如何初始化
私钥。很可能,您正在将
malloc()
delete
混合,并在过程中损坏堆。如果指针不是用
new
创建的,则需要为提供给它的指针提供
shared\u ptr
适当的删除器

    shared_ptr<RSA> r(RSA_new(), RSA_free);
    shared_ptr<EVP_PKEY> p(EVP_PKEY_new(), EVP_PKEY_free);
    shared_ptr<BIGNUM> bn(BN_new(), BN_free);
    vector<unsigned char> doc(0, 100);

    BN_set_word(bn.get(), RSA_F4);
    RSA_generate_key_ex(r.get(), 2048, bn.get(), 0);
    EVP_PKEY_set1_RSA(p.get(), r.get());
    rsa_sha512_sign(doc, p);
shared_ptr r(RSA_new(),RSA_free);
共享(EVP_PKEY_new(),EVP_PKEY_free);
共享(bn_new(),bn_free);
向量doc(01100);
BN_集_字(BN.get(),RSA_F4);
RSA_generate_key_ex(r.get(),2048,bn.get(),0);
EVP_PKEY_set1_RSA(p.get(),r.get());
rsa_-sha512_符号(doc,p);

EVP\u MD\u CTX\u create
初始化
MD
(代码)。另外,我添加它只是为了100%确定,但它仍然在同一个地方出现故障。很抱歉没有注意到这一点。你的代码对我有用。请检查您如何使用
共享\u ptr
。使用
valgrind
查看它是否为您识别罪犯。这就解决了问题。我不知道你不能那样做,谢谢!我接受了你的回答,但我还不能投票给你。