简体   繁体   English

使用没有证书的SSL

[英]using SSL without certificate

I am trying to use SSL without any certificate. 我正在尝试使用没有任何证书的SSL。 I've read that it is possible so I am writing code without the calls to set it. 我读过有可能,所以我在编写代码时没有调用它的设置。 According to the documentation it should be the right list of steps. 根据文档,它应该是正确的步骤列表。 Do you know if that is really possible? 你知道那是否真的可能吗?

I am using CENTOS 6.4. 我正在使用CENTOS 6.4。

When I run I always receive error 我跑步时总是会收到错误消息

 14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Below is my code for the Server 下面是我的服务器代码

  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;  
  }

And below the one for the client 和下面的一个为客户

    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. 我正在尝试使用没有任何证书的SSL。

You need to use Anonymous Diffie-Hellman (ADH) or Anonymous Elliptic Curve Diffie Hellman (AECDH). 您需要使用匿名Diffie-Hellman(ADH)或匿名椭圆曲线Diffie Hellman(AECDH)。 When using anonymous schemes, the server does not send its certificate. 使用匿名方案时,服务器不会发送其证书。

Call SSL_set_cipher_list before SSL_connect . SSL_set_cipher_list之前调用SSL_connect According to ciphers(1) , the cipher you want is aNULL . 根据ciphers(1) ,所需的密码是aNULL aNULL includes both ADH and AECDH . aNULL包括ADHAECDH


Do you know if that is really possible? 你知道那是否真的可能吗?

Yes, its possible. 是的,有可能。 But its a bad idea to use anonymous cipher suites because they are prone to active attacks. 但是使用匿名密码套件是一个坏主意,因为它们容易受到主动攻击。 That is, they can be Man-in-the-Middle'd. 也就是说,它们可以是中间人。

Also, most clients and servers are configured to reject anonymous cipher suites via "!aNULL" cipher suite list. 同样,大多数客户端和服务器都配置为通过"!aNULL"密码套件列表拒绝匿名密码套件。 So you might find in practice that you can't really connect to anything. 因此,您可能会在实践中发现您无法真正连接任何东西。

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

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