Why is OpenSSL 1.1.1 (Linux client) sending application data before Change Cipher Spec?

You're looking at TLS version 1.3, which has a quite different handshake than that of earlier versions.

In TLS 1.3, the "ChangeCipherSpec" message is meaningless – it is only sent to satisfy some intrusion detection systems which absolutely insist on seeing one (there are systems which try to block "malformed" TLS connections).

Additionally, all handshake messages following ServerHello are encrypted in TLS 1.3, and disguised as "Application Data" messages (to pacify firewalls and IDS systems) with the actual message type being hidden inside the encrypted payload.

So the first few "Application Data" messages in your log may actually contain handshake payloads such as the encrypted "Certificate" message, rather than the actual application request.


The "mac" in the message may pertain to the Message authentication code, meaning in this case that the message cannot be authenticated.

I would guess that the Linux client and the Nginx server are not using the same cipher or the same TLS version, while the Windows software uses the correct version.

So check the versions that are actually used or installed on both ends, or their configured parameters.