提升 asio ssl:如果私钥传递上下文::use_private_key,则不调用密码回调
Boost asio ssl: password callback not called if private key passed with context::use_private_key
我正在编写一个使用boost asio ssl的测试单元。
我在 Ubuntu 1.54 上使用 Boost 14.04 64 位。
我计划使测试自给自足,而不是依赖文件来指定私钥,因此我想在测试本身中对密钥及其密码进行硬编码(它们只是测试密钥和密码(。
代码如下。目前它什么都不做,但我只是试图在指定私钥时使密码回调工作:
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
MIIFJjCCAw4CCQDQjrFrRcdRkjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJTn
BLABLABLABLA";
std::string key = "-----BEGIN RSA PRIVATE KEY-----n
Proc-Type: 4,ENCRYPTEDn
DEK-Info: DES-EDE3-CBC,06622C22CAB27AC2n
n
JMudxXy4ZxB733xh7QO4elsVCTzJZuWl9Go4ZMuWx0DZb2fYHqXynKZSf7UactSwn
vhKJnLPZaa5U+xOr9cdpSd3SwtQyNu6yaVQH3af2ILRwUsw9mQmI8yqIIF1Y6AgVn
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_private_key
时,不会调用密码回调,我必须在控制台中手动输入密码。如果我用use_private_key_file
替换use_private_key
,则调用回调。
我希望在使用use_private_key
时也会调用password_callback
。
我错过了什么吗?
反映了底层OpenSSL API的限制:
加密仅适用于从文件加载密钥:
从文件加载的私钥可以加密。为了成功加载加密密钥,必须提供返回密码的函数,请参见ssl_ctx_set_default_passwd_cb(3(。(从技术角度来看,证书文件也可能被加密,但是没有意义,因为证书中的数据无论如何都被认为是公开的。
(来自ssl_ctx_use_privatekey_file(
请考虑在应用程序内部使用原始密钥。通过查看二进制文件应该很难发现原始密钥。当然,您可以将密钥分散在位中并手动加密它们,但请记住,坚定的攻击者总是可以弄清楚的。
这背后的基本原理可能是,只要密码不同时传递,就可以安全地传递受密码保护的密钥文件。一旦您将密钥嵌入到还包含用于解密它的密码短语的程序中,无论如何传递它本质上都是不安全的。
更新
事实上,通过修补 Boost Asio 来获得所需的行为应该不难:use_private_key
上下文成员函数最终调用支持密码回调的::PEM_read_bio_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 邮件列表,无论他们是否有兴趣将其添加为一项功能。
我必须更新此线程,因为我处于同样的情况。似乎现在已实现对此的支持:
https://github.com/boostorg/asio/blob/a2204b67f85cf63936a1daaacee830b6b69cec9f/include/boost/asio/ssl/impl/context.ipp#L845
好消息!
- std::make_shared和protected/private构造函数
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 使用 Key 对 C++ 中的哈希映射进行排序. 无法排序
- std::<key-value>不同类型的对向量
- .value( "key" , default) 不适用于空的 json 对象吗?
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- std::set<Key,Compare,Allocator>::find() 函数使用"<"运算符而不是"=="运算符背后的直觉是什么?
- std::move(key) 同时迭代unordered_map<字符串,字符串>?
- C++ - "private"单身人士?
- cpp / c ++中的grpc客户端代码,元数据x-api-key/x-goog-api-key不起作用,给了我语音A
- 将复制构造函数设置为private和=delete有什么区别
- 库设计混乱.. "public"/"private"(模板)标题,库文件..?
- 黄金描述的C++ "Key Function"是什么?
- 我是否必须在类中的所有变量C++设置为 private?
- QString& QString::operator=(const QByteArray&)' is private
- 错误 LNK2001:未解析的外部符号"private: static class Game Game::game_"
- 从更新查询获取'Cannot insert duplicate key'
- C++ API-MS-WIN-SERVICE-PRIVATE-L1-1-1.DLL依赖项问题
- 当变量在多个函数作用域中使用时,我应该在类 private 中声明该变量吗?
- 将数据添加到 CArray 会产生错误"cannot access private member declared in class 'CObject'"