c++ - 使用没有证书的 SSL

标签 c++ ssl openssl

我想在没有任何证书的情况下使用 SSL。我已经读到这是可能的,所以我正在编写代码而无需调用来设置它。 根据文档,它应该是正确的步骤列表。 你知道这是否真的可能吗?

我使用的是 CENTOS 6.4。

当我运行时总是收到错误

 14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

下面是我的服务器代码

  int main() {
    int res = -1;
    SSL_library_init();       
    SSL_load_error_strings();
    SSL_CTX *sslctx = SSL_CTX_new( SSLv23_server_method());

    res = SSL_CTX_set_cipher_list(sslctx,"aNULL");
    if(0 == res) {
        cerr << "SSL_CTX_set_cipher_list" << endl;
        std::exit(EXIT_FAILURE);
    }



    int res = -1;

    sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));

    addr.sin_family = AF_INET;
    addr.sin_port   = htons(kPort);
    memset(&addr.sin_zero,0,8);

    int sfd = socket(AF_INET,SOCK_STREAM, 0);
    if(sfd == -1) {
      cerr << "Socket Failed" << endl;
      std::exit(EXIT_FAILURE);
    }

    res = bind(sfd, (const sockaddr*)&addr, sizeof(addr));
    if(res == -1) {
      cerr << "Bind Failed" << endl;
      std::exit(EXIT_FAILURE);
    }

    res = listen(sfd,kBackLog);
    if(res == -1) {
      cerr << "Listen Failed" << endl;
      std::exit(EXIT_FAILURE);
    }

    sockaddr_in client_addr;
    socklen_t   client_addr_len;
    int cfd = accept(sfd, (sockaddr*)&client_addr, &client_addr_len);
    if(cfd == -1) {
      cerr << "Accept Failed" << endl;
      std::exit(EXIT_FAILURE);
    }

    cout << "Client Connected" << endl;

    // new SSL context.
    SSL *cSSL = SSL_new(sslctx);
    res = SSL_set_fd(cSSL, cfd);
    cout << res << endl;
    if(0 == res) {
      cerr << "Error on SSL_set_fd" << endl;
      close(sfd);
      std::exit(EXIT_FAILURE);
    }

    res = SSL_set_cipher_list(cSSL, "aNULL");
    if(0 == res) {
        cout << "failure on SSL_set_cipher_list";
        close(sfd);
        std::exit(EXIT_FAILURE);
    }



    //Here is the SSL Accept portion.  Now all reads and writes must use SSL
    cout << "call to SSL_accept" << endl;
    res = SSL_accept(cSSL);
    switch(res)
    {
      case 0:
      case -1: {
      cout << "error on SSL_accept("<< res << ")" << endl;
      std::exit(EXIT_FAILURE);
      }
    }

    char buf[4];
    res = SSL_read(cSSL, (char*)buf, 4);
    switch(res) {
      case  0:
      case -1: {
      cout << "error on SSL_read("<< res << ")" << endl;
      std::exit(EXIT_FAILURE);
     }  
    } 
    cout << buf << endl;  
  }

下面是给客户的

    int main() {
      int res = -1;
      SSL_library_init();       
      SSL_load_error_strings();
      //OpenSSL_add_all_algorithms(); I didn't find this in man pages.
      SSL_CTX *sslctx = SSL_CTX_new( SSLv23_client_method());


      res = SSL_CTX_set_cipher_list(sslctx,"aNULL");
      if(0 == res) {
        cerr << "SSL_CTX_set_cipher_list" << endl;
        std::exit(EXIT_FAILURE);
      }

      int res = -1;
      int sfd = socket(AF_INET, SOCK_STREAM, 0);
      CHECK(sfd,"socket");

      struct sockaddr_in addr;
      addr.sin_family      = AF_INET;
      addr.sin_port        = htons(kPort); 
      addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // #include <arpa/inet.h>

      res = connect(sfd, (const sockaddr*)&addr, sizeof(addr));
      CHECK(res, "connect");
      if(-1 == res) {
        cerr << "Error on Connect" << endl;
        close(sfd);
        std::exit(EXIT_FAILURE);
      }

      SSL *cSSL = SSL_new(sslctx);
      if(NULL == cSSL) {
        cerr << "Error on SSL_new" << endl;
        close(sfd);
        std::exit(EXIT_FAILURE);
      }

      res = SSL_set_fd(cSSL, sfd);
      if(0 == res) {
        cerr << "Error on SSL_set_fd" << endl;
        close(sfd);
        std::exit(EXIT_FAILURE);
      }

      res = SSL_set_cipher_list(cSSL, "aNULL");
      if(0 == res) {
        cout << "failure on SSL_set_cipher_list";
        close(sfd);
        std::exit(EXIT_FAILURE);
      }
      cout << "calling SSL connect" << endl;
      res = SSL_connect(cSSL);    
      switch(res) {
        case 0:
        case -1: {
         cerr << "Error on SSL_connect("<< res << ")" << endl;
         print_ssl_error(cSSL, res);
         close(sfd);
         std::exit(EXIT_FAILURE);
       }
      }

      cout << "SSL write" << endl;
      char buf[4] = {'a','b','c','\n'};
      SSL_write(cSSL, buf, 4);

      sleep(10);
      close(sfd);
    }

最佳答案

I am trying to use SSL without any certificate.

您需要使用匿名 Diffie-Hellman (ADH) 或匿名椭圆曲线 Diffie Hellman (AECDH)。使用匿名方案时,服务器不会发送其证书。

调用SSL_set_cipher_listSSL_connect 之前。根据ciphers(1) ,您想要的密码是 aNULLaNULL 包括 ADHAECDH


Do you know if that is really possible?

是的,这是可能的。但是使用匿名密码套件不是一个好主意,因为它们容易受到主动攻击。也就是说,它们可以是中间人。

此外,大多数客户端和服务器都配置为通过"!aNULL" 密码套件列表拒绝 匿名密码套件。因此,在实践中您可能会发现您无法真正连接到任何东西。

关于c++ - 使用没有证书的 SSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24912975/

相关文章:

ssl - SNI 是否在浏览器中实际使用和支持?

javascript - 有没有办法从 NativeScript 应用程序通过 SSL 与 WebSocket 通信?

ssl - 如何使用 nginx 反向代理在同一端口上从 http 重定向到 https

ssl - 我无法在我的网站中添加Comodo SSl,请您指导我

C++ 在模板编译器错误中使用模板

python - 将 C++ 类移植到 PyQt

c++ - SSL 与加密套接字

c - Eclipse CDT 中的 C 相当于 "Open Implementation"

python - Py_DECREF 段错误

c++ - 如何使用迭代器和 find/find_f 在类的 C++ vector 中查找实际值