Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.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++ Boost asio ssl:如果私钥随上下文一起传递,则不会调用密码回调::use_private_key_C++_Ssl_Boost_Boost Asio - Fatal编程技术网

C++ Boost asio ssl:如果私钥随上下文一起传递,则不会调用密码回调::use_private_key

C++ Boost asio ssl:如果私钥随上下文一起传递,则不会调用密码回调::use_private_key,c++,ssl,boost,boost-asio,C++,Ssl,Boost,Boost Asio,我正在编写一个使用boost asio ssl的测试单元 我在Ubuntu 14.04 64位上使用Boost1.54 我计划使测试自给自足,不依赖文件来指定私钥,因此我希望在测试本身中硬编码密钥及其密码(它们只是测试密钥和密码) 代码如下。现在它什么也不做,但我只是在指定私钥时尝试使密码回调工作: std::string password_callback( std::size_t max_length, boost::asio::ssl::context::password_purp

我正在编写一个使用boost asio ssl的测试单元

我在Ubuntu 14.04 64位上使用Boost1.54

我计划使测试自给自足,不依赖文件来指定私钥,因此我希望在测试本身中硬编码密钥及其密码(它们只是测试密钥和密码)

代码如下。现在它什么也不做,但我只是在指定私钥时尝试使密码回调工作:

std::string password_callback(
  std::size_t max_length,
  boost::asio::ssl::context::password_purpose purpose)
{
    return "test";
}

TEST(StreamReader, sslStream)
{

    std::string certificate = "-----BEGIN CERTIFICATE-----\n\
MIIFJjCCAw4CCQDQjrFrRcdRkjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJT\n\
BLABLABLABLA";

    std::string key = "-----BEGIN RSA PRIVATE KEY-----\n\
Proc-Type: 4,ENCRYPTED\n\
DEK-Info: DES-EDE3-CBC,06622C22CAB27AC2\n\
\n\
JMudxXy4ZxB733xh7QO4elsVCTzJZuWl9Go4ZMuWx0DZb2fYHqXynKZSf7UactSw\n\
vhKJnLPZaa5U+xOr9cdpSd3SwtQyNu6yaVQH3af2ILRwUsw9mQmI8yqIIF1Y6AgV\n\
BLABLABLABLA";

    boost::asio::io_service io_service;
    boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
    ctx.set_password_callback(password_callback);
    ctx.use_certificate(boost::asio::const_buffer(certificate.c_str(), certificate.size()), boost::asio::ssl::context::pem);
    ctx.use_private_key(boost::asio::const_buffer(key.c_str(), key.size()), boost::asio::ssl::context::pem);
    ctx.set_verify_mode(boost::asio::ssl::verify_peer);
}
当执行
use\u private\u key
时,不会调用密码回调,我必须在控制台中手动输入密码。如果我将
使用私钥
替换为
使用私钥文件
,则调用回调

我希望在使用
use\u private\u key
时也会调用
password\u callback


我遗漏了什么吗?

这反映了底层OpenSSL API的局限性:

EncOption仅适用于从文件加载密钥:

可以对从文件加载的私钥进行加密。为了成功加载加密密钥,必须提供返回密码短语的函数,请参阅ssl\u ctx\u set\u default\u passwd\u cb(3)。(从技术角度来看,证书文件也可能被加密,但这没有意义,因为证书中的数据无论如何都被认为是公共的。)

(来自)

考虑从应用程序内部使用原始密钥。通过查看二进制文件,很难发现原始密钥。当然,您可以将密钥分散成比特并手动加密,但请记住,一个坚定的攻击者无论如何都可以找到它

这背后的理由可能是,只要不同时传递密码短语,受密码短语保护的密钥文件就可以安全地传递。一旦您将密钥嵌入程序(该程序也包含用于解密密钥的密码短语),那么传递密钥本质上是不安全的

更新

事实上,通过修补Boost Asio来获得所需的行为并不困难:
use\u private\u key
上下文成员函数最终调用了
::PEM\u read\u bio\u PrivateKey
,它

你可以加上:

  //evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0);
  evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 
          handle_->default_passwd_callback,
          handle_->default_passwd_callback_userdata); // SEHE WAS HERE
为了得到你想要的行为


确保ping Asio开发者/boost邮件列表,看他们是否有兴趣将其作为一项功能添加。

我将在测试单元中使用密钥和pwd:密钥在测试之外是无用的,所以我不担心将其嵌入代码中。实际上,现在我正在检查boost:asio::context的内部,我看到代码调用了PEM_read_bio_PrivateKey,它也接受回调或密码短语作为参数,但它们被保留为null。我怀疑这可能是boostI中的一个bug,我想我的编辑和你的评论是对的。我刚刚尝试添加这些参数,它确实按预期工作。正如我在回答中已经提到的,我肯定会与boost开发人员讨论这个问题。被报道为bug的欢呼声(我正在努力清理报告中的降价…)