我们将openssl 1.0.2k用于TLS相关功能。 在我们的部署之一中,客户端能够使用TLSv1.2完成TLS握手,并能够向服务器发送应用程序数据。在某些请求之后,TLS连接从服务器端关闭,并出现以下错误 “错误:1408F10B:SSL例程:SSL3_GET_RECORD:版本号错误”
TLS握手步骤:
1. Client hello
2. Server Hello
3. Certificate,Certificate Request, Server hello done
4. Certificate,Client Key Exchange,Change Cipher spec,Encrypted handshake message
5. Change Cipher spec,Encrypted handshake message
6. Application data exchanges between client and server
7. Encrypted Alert(server to client)
8. Encrypted Alert( client to server
服务器端的错误日志显示“错误:1408F10B:SSL例程:SSL3_GET_RECORD:版本号错误”
能否让我们知道此问题的原因。如果ssl版本不匹配,那么握手阶段应该不会成功,对吧? 但是在我们这种情况下,握手成功,并且在某些应用程序数据传输之后,我们的服务器因该错误而失败。
答案 0 :(得分:0)
如果ssl版本不匹配,那么握手阶段应该不会成功,对吗?
不。任何TLS数据包都具有标头,并且标头内部具有TLS版本:
(
byte - record_type
byte[2] - version
byte[2] - length
) header
byte[length] - encrypted or raw data
标题始终是原始的,永远不会加密。即使在握手期间客户端在所有TLS数据包中发送了TLS 1.2版本,他也可以在握手完成后发送另一个版本。或者介于两者之间的某人可以修改网络流量。在这种情况下,OpenSSL会抛出描述的错误。
答案 1 :(得分:0)
就我而言,我使用OpenSSL来实现客户端功能。
我在 SSL_connect 之后呼叫 SSL_set_connect_state 。应该先调用它。
SSL_set_connect_state(仅适用于客户端)清除所有状态!
摘要:
void SSL_set_connect_state(SSL *s)
{
s->server = 0;
s->shutdown = 0;
ossl_statem_clear(s);
s->handshake_func = s->method->ssl_connect;
clear_ciphers(s);
}
就我而言:
1)客户端<->服务器握手成功。 2)客户端SSL_write(客户端向服务器发送消息)导致与问题(服务器端)完全相同的错误
我在服务器端查看了pkt转储。
从0x2651570 [0x2656c63]中读取(5个字节=> 5(0x5))。
0000- 16 03 01 01 e2 .....错误 139688140752544:错误:1408F10B:SSL例程:SSL3_GET_RECORD:错误>版本号:s3_pkt.c:337:
1)上面摘录的5个字节是SSL记录的大小。服务器收到数据,并尝试读取SSL记录。
2)记录的第一个字节是SSL记录类型,在这种情况下===> x16 =>'22'
这本身是错误的,就服务器而言,握手成功并且正在等待应用程序数据。相反,它收到具有握手的SSL记录的数据,因此引发了错误。
应用程序数据的正确摘要如下:'x17'==> 23
从0x2664f80 [0x2656c63]中读取(5个字节=> 5(0x5))。
0000- 17 03 03 00 1c
由于连接后调用了SSL_set_connect_state,因此客户端状态丢失,并且如果之前未执行握手(客户端认为其状态已丢失!),则SSL_write将尝试握手。
可以在以下位置找到有关这些SSL记录的更多数据: https://www.ibm.com/support/knowledgecenter/SSB23S_1.1.0.12/gtps7/s5rcd.html