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_read
和SSL_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:从客户端发起的重新协商的主要内容,如果未能解决你的问题,请参考以下文章