OpenSSL:从客户端发起的重新协商

Posted

技术标签:

【中文标题】OpenSSL:从客户端发起的重新协商【英文标题】:OpenSSL: Renegotiation initiated from client 【发布时间】:2018-10-10 06:28:27 【问题描述】:

我使用 mem-BIO 设置客户端-服务器连接。我能够在没有套接字 IO 的情况下发送数据。这是我的参考资料 - http://roxlu.com/2014/042/using-openssl-with-memory-bios

问题 1: 对于解密,它使用 BIO_write() 和 SSL_read()。如果通过套接字 IO,记录超过 2 个数据包,我需要注意什么?如果 SSL_read() 返回 SSL_ERROR_WANT_READ,是否意味着数据在 in_bio 中缓冲,我需要为第二个数据包再次调用 BIO_write() 和 SSL_read(),而这一次 SSL_read() 将返回 SSL_ERROR_NONE?

问题 2: 我试图了解 SSL 重新协商握手。它会再次进行 4 次握手吗?还是应该只进行两次握手并且可能不再需要客户端问候?请分享有关重新协商握手交换的任何信息。

现在,我已将此代码添加到上述参考示例中:

main() 
<snip - Initial handshake>
</snip>

  SSL_renegotiate(client.ssl);
  SSL_do_handshake(client.ssl);
  krx_ssl_handle_traffic(&client, &server);
  krx_ssl_handle_traffic(&server, &client);
  krx_ssl_handle_traffic(&client, &server);
  krx_ssl_handle_traffic(&server, &client);

我通过回调看到了这些:

+ client:      HANDSHAKE START -  before connect initialization  - CINIT
+ client:                 LOOP -        SSL renegotiate ciphers  - UNKWN
+ client:                 LOOP -     SSLv3 write client hello A  - 3WCH_A
+ server:      HANDSHAKE START -   before accept initialization  - AINIT
+ server:                 LOOP -   before accept initialization  - AINIT
+ server:                 LOOP -      SSLv3 read client hello A  - 3RCH_A
+ server:                 LOOP -     SSLv3 write server hello A  - 3WSH_A
+ server:                 LOOP -      SSLv3 write certificate A  - 3WSC_A
+ server:                 LOOP - SSLv3 write certificate reques  - 3WCR_A
+ server:                 LOOP -      SSLv3 write server done A  - 3WSD_A
+ server:                 LOOP -               SSLv3 flush data  - 3FLUSH
+ client:                 LOOP -      SSLv3 read server hello A  - 3RSH_A
+ client:                 LOOP - SSLv3 read server certificate   - 3RSC_A
+ client:                 LOOP - SSLv3 read server certificate   - 3RCR_A
+ client:                 LOOP -       SSLv3 read server done A  - 3RSD_A
+ client:                 LOOP - SSLv3 write client certificate  - 3WCC_A
+ client:                 LOOP - SSLv3 write client key exchang  - 3WCKEA
+ client:                 LOOP - SSLv3 write certificate verify  - 3WCV_A
+ client:                 LOOP - SSLv3 write change cipher spec  - 3WCCSA
+ client:                 LOOP -         SSLv3 write finished A  - 3WFINA
+ client:                 LOOP -               SSLv3 flush data  - 3FLUSH
+ server:                 LOOP - SSLv3 read client certificate   - 3RCC_A
+ server:                 LOOP - SSLv3 read client key exchange  - 3RCKEA
+ server:                 LOOP - SSLv3 read certificate verify   - 3RCV_A
+ server:                 LOOP -          SSLv3 read finished A  - 3RFINA
+ server:                 LOOP -   SSLv3 write session ticket A  - UNKWN
+ server:                 LOOP - SSLv3 write change cipher spec  - 3WCCSA
+ server:                 LOOP -         SSLv3 write finished A  - 3WFINA
+ server:                 LOOP -               SSLv3 flush data  - 3FLUSH
+ server:       HANDSHAKE DONE - SSL negotiation finished succe  - SSLOK
+ client:                 LOOP - SSLv3 read server session tick  - UNKWN
+ client:                 LOOP -          SSLv3 read finished A  - 3RFINA
+ client:       HANDSHAKE DONE - SSL negotiation finished succe  - SSLOK

谢谢。

【问题讨论】:

关于问题 2,您是否阅读了en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake 和“恢复 TLS 握手”部分?它描述得很好。这也是一份简历,而不是重新谈判。重新协商有另一种含义(在现有 TLS 握手中更改加密参数),现在认为这比解决方案问题更多,因此它被禁用/不推荐,例如参见 sslshopper.com/… 至于问题1,你看wiki.openssl.org/index.php/SSL/TLS_Client了吗?它在 openssl 中展示了一个基本的 TLS 客户端,提供了许多细节。 Patrick:Q 明确提到了重新谈判。尽管在 Apache 缺陷被(很好地)公开后,重新谈判被短暂回避,但 RFC 5746 于 2010 年 2 月问世,几乎所有实现都在几个月或最多一年内支持它。 【参考方案1】:

第一季度。数据包和_WANT_READ

您根本不清楚您的数据包是什么。当在 TCP 上使用 SSL/TLS(正常情况)时,SSL/TLS 记录最多可以超过 16k 八位字节,而在 大多数 网络路径上,TCP 通常使用大小为大约1400。完成一个记录可能需要10多个这样的数据包。当它发生时,该记录可能不是 ApplicationData 记录;如果不是,SSL_read 仍然没有要返回的数据,而是会根据协议进行操作,这可能涉及在返回数据之前进一步读取和/或写入。你不应该猜测非阻塞SSL_read(或SSL_write)会做什么;您应该始终查看它们的返回值,以及来自SSL_get_error 的“扩展”值(这是实际返回SSL_WANT_READ,WRITE 等的例程,而不是SSL_readSSL_write)。手册页对此进行了解释,如果您还没有阅读,我鼓励您阅读。如果您在不使用手册页的非 WSL Windows 上,请参阅the website。

第二季度。重新协商

(注意:仅通过 1.2 回答 TLS;1.3 肯定会极大地改变正常的握手,我相信也会重新协商,但我还没有详细讨论过。)除了它在会话时开始(加密context) 已经在使用中,可能由服务器发起 RequestHello,并且(重要的是)可以使用 Renegotiation Indication 扩展 (RFC5746) 来防止“Apache-splice”攻击 (CVE-2009 -3555),重新协商(几乎)与初始协商相同。如果完全握手,则需要四次飞行(两次往返);如果一个简短的握手(恢复一个预先存在的会话)它需要三个航班,但最后一个可以与客户数据相结合,经常将其减少到一次往返。请参阅我在https://security.stackexchange.com/questions/91248/questions-about-triple-handshakes-considered-harmful-breaking-and-fixing-authen 的回答(其相关性固然不明显),以获得关于此的即兴表演。握手见RFC 5246 et pred

【讨论】:

以上是关于OpenSSL:从客户端发起的重新协商的主要内容,如果未能解决你的问题,请参考以下文章

内容协商与转码

无需 ssl 重新协商的 ssl 客户端身份验证

客户何时适合与 SignalR 服务重新协商?

如何使 CLIENT-CERT SSL 重新协商在 Jetty 中工作?

使用curl指令发起websocket请求

ssh 登录