YAP(Yet Another Protocol) is a session layer protocol which provides secure data transmission.
1. Protocol Description
YAP runs on top of TCP. It is mainly designed for proxies. Currently YAP is only a draft, and a large part of its content is not explicitly defined.
Despite the first packet, Each YAP packet is the concatenation of the following three parts of data.
1.1.1 Secret Header
A Secret Header is a chunk of encrypted data. It is encrypted with a symmetric cryptographic algorithm(namely AES) known to both the client and the server. The length of its plaintext is fixed to 16 bytes, thus the length of the Secret Header is confirmed. The shared key to the encryption is calculated using your private key and the other side's public key.
The first two bytes of a Secret Header is an unsigned short which indicates the length of the Message Body(without prefix). The next two bytes is the length of Arbitrary Bytes. The last 12 bytes should be cryptographically secure pseudo-random bytes, which is used as the key to crypt the Message Body after being hashed.
1.1.2 Message Body
The Message Body is encrypted with an algorithm not necessarily the same as the one used for the Secret Header. The first two bytes of the decrypted message is the length of the actual message.
1.1.3 Arbitrary Bytes
The Arbitrary Bytes should be a chunk of cryptographically secure pseudo-random bytes.
YAP uses public key cryptography to generate shared keys, and symmetric cryptography for message encryption.
The algorithm YAP uses as public key cryptography is NISTP521. Public key length is 158 bytes, with fixed first 26 bytes, and the 27th byte no other than 0x00 or 0x01.
Theoretically all symmetric cryptography can be used for message decryption in YAP. For security purpose, AES-256-GCM is highly recommended.
There should be a stage identifier for each established connection, which determines the behaviors of both the client and the server.
Once a connection is established, the server waits for the client to send a part of its public key(start from the 27th byte, the 27th byte shall add a random multiplier of 2), followed by a packet whose message is recognizable by the server. The server respond with a packet which contains corresponding(can be identical) message. Upon the client receives the packet, proceed to the next stage. Otherwise, if either the server or the client receives a bad packet, close the connection.
- The public key used in this stage is the only exposed plaintext data in YAP. Using the same key multiple times makes you more vulnerable to attackers and sniffers. However, in less serious circumstances, this matter is trivial(so why don't you just use socks5 or something like that?).
This stage has two purposes, one is authentication, through which server decides whether the connected client has access to the service. The second is key renewal. A new set of public keys are provided to each other for further encryption. If successful, proceed to the next stage. Otherwise close connection or send an error message.
- In this stage, client and server can negotiate further cryptographic algorithms, or other parameters.
The server waits for client to specify the address and port of the remote server. Upon successfully parsed the request, the server opens a connection to the remote server, and proceed to the next stage. Otherwise, send an error message.
In this stage, the server transfers data between the client and the remote server. When the remote server closes connection, inform the client and go back to STAGE_ADDR. If the client send a request to close the remote connection, do the same.
In STAGE_STREAM, the client and the server uses opcodes to determine the type of the message.
- If packet format is normal, the message shall be transferred between the client and the server.
- If the first two bytes of the message body is zero, then the message is considered an opcode. 0x00 indicates that something went wrong. 0x01 Indicates closing the remote connection. 0x02 indicates close the current connection. You may define other opcodes for switching algorithms or keys, etc.
- Opcodes are not limited to one byte.
As you can see, inefficiency is the price YAP pays for security. For each packet, encryption/decryption is done two times. Another problem is that generating keys is very slow. It's recommended to maintain a key stack. Calculating shared keys is also slow, thus reusing connections is essential.
- YAP flow can be easily detected by checking whether the first packet contains public key(A random string can hardly be a valid ECC key). This problem can be prevented by using a previously generated random key instead of public key. Upon receiving the key, the server use it to fetch the real key from memory or database.
- The Arbitrary Bytes are essential for anti-sniffing. Make sure they are random enough, and it's a wise choice to send them separately.
This project is actually an executable demo written in PHP, implementing a proxy server using YAP.
2.1 Why PHP?
Well, believe me, it's faster than python and Node.js. And I'm not in the mood for writing a C++ demo.
- I haven't done ANY tests on this demo yet, and I doubt my code is strong enough to be used directly without testing. But don't worry, I'll work on it soon enough.
- This demo is for educational use only. Any possible consequences shall be undertaken by the user himself.