【问题标题】:What data must be sent after sending a STARTTLS command to an email server向电子邮件服务器发送 STARTTLS 命令后必须发送哪些数据
【发布时间】:2015-11-11 23:43:11
【问题描述】:

我正在用 C++ 编写一个电子邮件客户端,使用 Winsock2 API 通过 SMTP 从 Gmail 帐户发送电子邮件。我没有使用任何其他第三方库。

我已在端口 587(用于 TLS)上连接到 Gmail 服务器并发送了基本的 EHLO 和 STARTTLS 命令,但我的问题是,在发送 STARTTLS 命令后我应该具体发送哪些数据?

为了清楚起见,这是服务器输出:

显然 TLS 握手在 STARTTLS 命令之后进行,但是在 TLS 握手期间必须发送的第一条和后续数据是什么?根据我的阅读,它应该是交换安全证书等的二进制数据,但我找不到具体应该首先发送哪些数据。

我已经搜索了许多与此类似的问题,但我没有找到一个回答说必须在 STARTTLS 之后发送的特定数据。我知道 OpenSSL 的存在,我不会接受任何告诉我安装它的答案。

【问题讨论】:

    标签: c++ windows email winsock2 tls1.2


    【解决方案1】:

    SMTP STARTTLS 命令的语义和处理规则记录在RFC 3207 中。

    在您收到对STARTTLS 命令的成功 220 响应后,您必须开始 TLS 握手以建立加密,以加密/解密后续 SMTP 命令/响应。握手完成后,SMTP 状态将重置,因此您必须发出新的(现已加密的)EHLO 命令,然后根据需要继续执行剩余的(加密的)SMTP 命令。

    MSDN 记录了Transport Layer Security Protocol 的高级概述,并附有TLS Handshake Protocol 的分步说明。每个步骤的具体细节记录在RFC 2246 (TLS 1.0)、RFC 4346 (TLS 1.1) 和 RFC 5246 (TLS 1.2) 的第 7 节中。

    因此,除非您打算从头开始实施 TLS(请不要!!),否则您需要使用第三方库,例如 OpenSSL,或者您可以使用 Microsoft 的 Secure Channel API 来处理为您提供 TLS 握手和后续加密。

    【讨论】:

    • 请仔细阅读我的问题。我已经知道我必须在 STARTTLS 命令之后执行 TLS 握手,我特意询问我应该为握手发送什么数据。我已经阅读了给出的 RFC,但它仍然没有告诉我要发送什么数据。例如。它指定我必须在从服务器获得回复后发送证书结构,但我已经尝试过,并且刚刚从服务器获得“准备启动 tls”回复。我再次要求在 STARTLS 之后专门发送数据,以便与电子邮件服务器进行 TLS 握手。
    • @shmoo:我确实读过你的问题。如果您注意我指出的 RFC,它们会准确地告诉您要发送什么以及何时发送。您不能执行 TLS 握手,除非服务器首先发送 STARTTLS 220 回复,如 RFC 3207 中所定义。然后执行握手,首先发送 TLS ClientHello 记录并接收 ServerHello 记录,如定义在 RFC 2246、4346 和 5246 的第 7 节(“TLS 握手协议”)中。您需要更仔细地阅读 RFC,您正在寻找的答案都记录在其中。
    • @shmoo:如果您阅读了我指出的 MSDN 文档,它将为您提供一个非常清晰的 TLS 握手分步概述。 RFC 为您提供每个步骤的具体技术细节(格式和内容)。
    • @shmoo Yuor 的评论很荒谬。这些 TLS RFC。如果您认为他们没有详细说明握手,那么您就无法阅读它们。但是,如果您希望自己实现 SSL,那么您现在应该忘记这一点。使用 OpenSSL 或其他现有库之一。这是一项艰巨的工作。
    • 不,ClientHello 在发送 STARTTLS 命令后不起作用,是的,我已经阅读了 RFC,但是服务器不接受我发送的任何内容
    猜你喜欢
    • 2010-12-11
    • 2010-09-28
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多