【问题标题】:c++ Boost asio error: no shared cipherc ++ Boost asio错误:没有共享密码
【发布时间】:2015-10-14 20:16:19
【问题描述】:

我目前正在使用 boost asio 设置 RESTful API。

通过 HTTP 从客户端连接可以正常工作。但是,如果我尝试通过 HTTPS 连接,我会在服务器端收到错误消息:“没有共享密码”。 该错误似乎来自 openssl 实现,但我不知道该怎么做。我的第一个猜测是没有设置密码算法,但我看不到如何在 asio 中完成。

这是我在代码中输入的内容以及发生错误的位置:

auto acceptHandler = boost::bind(&self::onAccept, this, connection,
                                 boost::asio::placeholders::error);
connection->async_accept(m_acceptor, acceptHandler);

m_sslContext.set_options(
        context::default_workarounds | context::no_sslv2 | context::single_dh_use);
m_sslContext.use_certificate_file(filename, context::pem);
m_sslContext.use_private_key_file(filename, context::pem);

任何人以前有过这个或得到它的工作?

【问题讨论】:

    标签: c++ boost ssl boost-asio


    【解决方案1】:

    我遇到了同样的问题并以这种方式解决了。您必须为您的服务器生成私钥和证书文件。这是这样做的过程:

    // Generate a new ssl private key :
    $openssl genrsa -out privkey.pem 1024
    
    // Create a certificate signing request using your new key
    $openssl req -new -key privkey.pem -out certreq.csr
    
    // Self-sign your CSR with your own private key:
    $openssl x509 -req -days 3650 -in certreq.csr -signkey privkey.pem -out newcert.pem
    
    // Install the signed certificate and private key for use by an ssl server
    // This allows you to use a single file for certificate and private key
    $( openssl x509 -in newcert.pem; cat privkey.pem ) > server.pem
    
    // If you use a dh temp file :
    $openssl dhparam -outform PEM -out dh512.pem 512
    

    然后,将server.pemdh512.pem 文件复制到您的服务器执行目录中。

    如果你使用 tmp dh 文件你还必须添加这行代码m_sslContext.use_tmp_dh_file("dh512.pem");

    【讨论】:

    • 您应该更喜欢使用 dh2048,否则可能会抛出异常“DH512 失败 - dh 密钥太小”
    【解决方案2】:

    将未配置的boost::asio::ssl::context 对象提供给boost::asio::ssl::stream 对象构造函数时出现同样的错误,然后将其用作接受的结果套接字:

    server()
        : m_acceptor(/*args*/)
        , m_context(boost::asio::ssl::context::tlsv1_server)
        , m_stream(m_io_service, m_context)
    {
        // `m_context` configuring, BUT `m_stream` is unaffected
        m_acceptor.async_accept(m_stream.lowest_layer(), accept_result_handler);
    }
    // run somewhere `m_io_service.run()`, or other processor of `async` operations.
    

    在实际接受连接并在其上处理握手之后,握手处理程序会收到值为 336109761 的 boost::system::error_code 和消息 no shared cipher

    所以先创建和配置boost::asio::ssl::context,然后用它构造boost::asio::ssl::stream

    typedef boost::asio::ip::tcp::socket socket_type;
    typedef boost::asio::ssl::stream<socket_type> stream_type;
    
    std::shared_ptr<stream_type> m_stream;
    
    server()
        : m_acceptor(/*args*/)
        , m_context(boost::asio::ssl::context::tlsv1_server)
    {
        // `m_context` configuring
        m_stream = std::make_shared<stream_type>(m_io_service, m_context);
        m_acceptor.async_accept(m_stream->lowest_layer(), accept_result_handler);
    }
    

    不要忘记为每个新连接创建新流,上下文可以相同。

    【讨论】:

      【解决方案3】:

      正如@asiocity 指出的那样,重要的部分是完全配置 ssl::context 初始化 ssl::stream 之前。

      很难在初始化列表中同时初始化它们,同时仍然推迟 ssl::stream 直到 ssl::context 完全配置。

      我使用的一种方法是子类化 ssl::context 并覆盖构造函数,以便在初始化 ssl::stream 之前可以在初始化器列表中对其进行完全配置。

      例如

      class server_context : public boost::asio::ssl::context {
        public: server_context(boost::asio::ssl::context::method m, std::string certfile);
      };
      

      ...

      server_context::server_context(boost::asio::ssl::context::method m, std::string certfile)
      : boost::asio::ssl::context(m)
      {
        use_private_key_file(certfile);
        use_certificate_chain_file(certfile);
      }
      

      ...

      class myclass {
        private:
          server_context : ssl_context_;
          boost::asio::ssl::stream<boost::asio::ip::tcp::socket&> stream_;
        public:
          myclass(boost::asio::ip::tcp::socket&, std::string certfile);
      

      ...

      myclass::myclass(std::string certfile) 
      : ssl_context_(boost::asio::ssl::context::sslv23, certfile),
        stream_(socket, ssl_context_) 
      {
        ...
      }
      

      然而,要避免 shared_ptr 似乎需要做很多工作

      我希望/希望有一些构造函数-mixin/模板技巧,可以让我只使用自定义初始化列表而不是子类来做到这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-27
        • 2019-03-29
        • 2011-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-21
        相关资源
        最近更新 更多