【问题标题】:SMTPS: OpenSSL - SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol s23_clnt.c:787:SMTPS:OpenSSL - SSL 例程:SSL23_GET_SERVER_HELLO:未知协议 s23_clnt.c:787:
【发布时间】:2014-04-22 09:32:12
【问题描述】:

我正在使用 OpenSSL 来加密一些由硬件发送的电子邮件。但是,每当我尝试调用 SSL_connect() 时,我都会得到: SSL 例程:SSL23_GET_SERVER_HELLO:未知协议

发送“EHLO”和“STARTTLS”后,我调用以下函数:

SSL_CTX *ctx = NULL;
SSL *ssl = NULL;

    void CreateTLSSession(int sockfd)
    {
        printf("///////////////creating TLS Session/////////////////////\n");
        SSL_library_init();
        SSL_load_error_strings();
        OpenSSL_add_all_algorithms();
        ctx = SSL_CTX_new(SSLv23_client_method());
        if (ctx == NULL)
        {
            printf("failed to initialize context\n");
            return;
        }
        SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
        ssl = SSL_new(ctx);
        if (!SSL_set_fd(ssl, sockfd))
        {
            printf("failed to bind to socket fd\n");
            return;
        }
        if (SSL_connect(ssl) < 1)
        {
            ERR_print_errors_fp(stdout);
            fflush(stdout);
            printf("SSL_connect failed\n");
            return;
        }
    }

我已经尝试连接到:

  • smtp.live.com : 587 --> SSL 例程:SSL23_GET_SERVER_HELLO:unknown 协议 s23_clnt.c:787:
  • smtp.live.com : 25 --> SSL 例程:SSL23_GET_SERVER_HELLO:unknown protocol s23_clnt.c:787:
  • smtp.gmail.com : 587 --> SSL 例程:SSL23_GET_SERVER_HELLO:unknown 协议 s23_clnt.c:787:
  • smtp.gmail.com : 465 --> 服务器根本没有响应!
  • smtp.gmail.com : 25 --> SSL 例程:SSL23_GET_SERVER_HELLO:unknown
    协议 s23_clnt.c:787:

我尝试了不同的端口,因为关于此 SO 的一些类似问题表明,此类错误通常与使用错误的 SSL 端口有关。

我错过了什么吗?

更新:

所有其他方法(即 TLSv1_1_method()、SSLv3_method() ...)导致 SSL3_GET_RECORD:错误的版本号

更新:

我能够在wireshark上观察到以下内容:

“EHLO”

“为您服务”

“STARTTLS”

“准备开始”

-->现在我调用上面的函数

不可读的请求(加密)

不可读的回复(加密)

--> 错误

【问题讨论】:

标签: c ssl smtp openssl smtps


【解决方案1】:

底层 socked 是非阻塞的。通过使用select 并等待 TLS 握手完成,问题已解决。

【讨论】:

    【解决方案2】:

    解决此问题的另一种方法可能是在 Scott Gifford 的sslclient 下运行您的 C 程序(请参阅http://www.superscript.com/ucspi-ssl/sslclient.html)。 sslclient 将生成您的程序并打开与服务器的 tcp 连接,并将程序的标准输出通过管道传输到服务器,并将服务器的输出通过管道传输到程序的标准输入。他有一个 TLS 的补丁版本,它将以纯文本形式启动连接,然后一旦双方就 STARTTLS 达成一致,您的程序可以通过向文件描述符写入命令来向 sslcient 发出信号,以在连接上启用 SSL 加密。目的。这样做的好处是您可以让 sslclient 承担所有繁重的工作,例如设置套接字和 ssl 等,并且您可以专注于程序的核心功能。

    【讨论】:

      【解决方案3】:

      端口 587 和 25 上的 SMTP 服务器通常是纯文本,只有在初始 SMTP 对话和来自客户端的 STARTTLS 命令之后才会切换到 TLS。在纯文本套接字上尝试 SSL_connect 将失败。

      【讨论】:

      • 嗯,我从“EHLO”开始,然后是“STARTTLS”(到目前为止还没有加密),然后我调用上面提到的函数。从这里开始,通信应该被加密!
      • 您也必须检查来自服务器的响应,例如SSL_connect 只有在您从服务器获得对 starttls 的完整响应并且响应成功后才能启动。
      • 没错。我从服务器“准备好开始 STARTTLS”后调用 SSL_connect。还要检查我的问题中的更新。
      猜你喜欢
      • 1970-01-01
      • 2014-02-03
      • 2023-03-31
      • 2019-03-12
      • 1970-01-01
      • 2015-11-29
      • 1970-01-01
      • 2016-01-11
      • 2014-04-23
      相关资源
      最近更新 更多