swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.25k stars 3.16k forks source link

Handling Encrypted Packet Splitting in PHP Swoole #5267

Open moradi-morteza opened 2 months ago

moradi-morteza commented 2 months ago

I am currently developing a TCP server using PHP Swoole and implementing a backend based on the MTProto protocol. In this setup, clients send an initial packet structured as {[Key, IV] + [Data Length] + [Data]}, where both the data length and data are encrypted.

Upon receiving this, the server utilizes the provided key and IV to decrypt the data length, enabling it to understand and segregate the incoming data accordingly. Moreover, the server is designed to generate an AES-CTR encryption key from this initial packet, which is then employed to decrypt subsequent packets.

However, I'm facing challenges with the nature of encrypted packet length as the server requires the decryption key in advance to determine the split points for incoming packets. This scenario is managed in Swoole by setting open_length_check to false and customizing the package_length_func for packet splitting. My main issue arises with retaining and utilizing the initial decryption key for processing future packets, as I haven't found a way to efficiently store this key post its initial receipt.

I seek advice or solutions on the following:

Strategies for effectively saving and reusing the decryption key obtained from the first packet. Best practices for managing the decryption and splitting of encrypted packets in a PHP Swoole environment, especially under the constraints of the MTProto protocol. Any insights, examples, or guidance on tackling these issues would be greatly appreciated.

Thank you in advance for your assistance.

deminy commented 2 months ago

Strategies for effectively saving and reusing the decryption key obtained from the first packet.

There are different ways. In the old days you can store it to a dynamic property on the Server object; however, since dynamic property is deprecated in PHP, this option is no longer recommended. Another quick way to do it is with Swoole Table or APCu. You can check this examaple on how to use APCu with Swoole.

Best practices for managing the decryption and splitting of encrypted packets in a PHP Swoole environment, especially under the constraints of the MTProto protocol.

If these operations take time and slow down the TCP server, you can add task worker processes to the server and use them to handle CPU-intensive tasks (e.g., decryption/encryption). By doing this, the TCP server can still handle new incoming requests while busy decrypting/encrypting packets for other requests. Here is a quick example. The example uses an HTTP server, but the ideas are of the same.