繁体   English   中英

在不关闭连接的情况下在循环中增强 asio 加密

[英]boost asio encryption in a loop without closing connection

我正在尝试扩展 boost asio 库中的示例。 到目前为止我所取得的成功。

1) 运行 echo 客户端和服务器。

http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/example/cpp11/echo/blocking_tcp_echo_client.cpp

http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/example/cpp11/echo/blocking_tcp_echo_server.cpp

2) 扩展回显服务器以读取消息,直到标准输入的文件结束。

3) 运行 ssl 客户端服务器示例。

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/ssl/client.cpp

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/ssl/server.cpp

我需要什么帮助:我希望能够将发送/接收的消息放入客户端的循环中。 我不想绕圈子

client c(io_service, ctx, iterator);
io_service.run();

因为这将验证每条消息的证书。 我尝试在 handle_handshake 和其他函数周围放置一个循环,但它们不起作用。 直到函数结束才会发生发送。 我永远不会收到回复。

我愿意避免使用异步 IO,但我仍然想要加密。

我必须从阻塞客户端开始,并使用 https 从 ssl 客户端和 ssl 示例中添加我需要的内容:

这适用于未经修改的 ssl 服务器。

//
// ssl_blocking_tcp_echo_client.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

using boost::asio::ip::tcp;

enum { max_length = 1024 };

  bool verify_certificate(bool preverified,
      boost::asio::ssl::verify_context& ctx)
  {
    // The verify callback can be used to check whether the certificate that is
    // being presented is valid for the peer. For example, RFC 2818 describes
    // the steps involved in doing this for HTTPS. Consult the OpenSSL
    // documentation for more details. Note that the callback is called once
    // for each certificate in the certificate chain, starting from the root
    // certificate authority.

    // In this example we will simply print the certificate's subject name.
    char subject_name[256];
    X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
    X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
    std::cout << "Verifying " << subject_name << "\n";

    return preverified;
  }

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 3)
    {
      std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n";
      return 1;
    }


    boost::asio::io_service io_service;
    boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
    ctx.load_verify_file("server.crt");
    ctx.set_verify_mode(boost::asio::ssl::verify_peer);
    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket(io_service, ctx);

    tcp::resolver resolver(io_service);
    boost::asio::connect(socket.lowest_layer(), resolver.resolve({argv[1], argv[2]}) );
    socket.set_verify_callback(
        boost::bind(&verify_certificate, _1, _2));
    socket.handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::client);

    while(std::cin)
    {
        std::cout << "Enter message: ";
        char request[max_length];
        std::cin.getline(request, max_length);
        size_t request_length = std::strlen(request);
        boost::asio::write(socket, boost::asio::buffer(request, request_length));

        char reply[max_length];
        size_t reply_length = boost::asio::read(socket,
            boost::asio::buffer(reply, request_length));
        std::cout << "Reply is: ";
        std::cout.write(reply, reply_length);
        std::cout << "\n";
    }

  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}

在开始之前,我根据 Shootfast 对这个问题的回答修改了服务器和客户端。 我不得不稍微修改它,因为有些东西太短了。 我将此命令更改为 2048 而不是原来的 512。

openssl dhparam -out dh512.pem 2048

下面引用。

好的,对于将来发现此问题的任何人,您需要创建证书并对其进行适当签名。 以下是Linux的命令:

//生成私钥

openssl genrsa -des3 -out server.key 1024

//生成证书签名请求

openssl req -new -key server.key -out server.csr

//使用私钥签署证书

openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

//删除密码要求(例如需要)

cp server.key server.key.secure
openssl rsa -in server.key.secure -out server.key

//生成dhparam文件

openssl dhparam -out dh512.pem 2048

完成后,您需要更改 server.cpp 和 client.cpp 中的文件名。

服务器.cpp

context_.use_certificate_chain_file("server.crt"); 
context_.use_private_key_file("server.key", boost::asio::ssl::context::pem);
context_.use_tmp_dh_file("dh512.pem");

客户端

ctx.load_verify_file("server.crt");

那么它应该一切正常!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM