/src/content/en/spec/03-one-time-auth.md

https://gitlab.com/Mirros/shadowsocks-org · Markdown · 55 lines · 39 code · 16 blank · 0 comment · 0 complexity · e4bd452c9e2ceeca3d19cbaae6d47c69 MD5 · raw file

  1. One-time authentication (shortened as _OTA_) is a new experimental feature designed to improve the security against [CCA](https://en.wikipedia.org/wiki/Chosen-ciphertext_attack). You should understand the [protocol](protocol.html) before reading this document.
  2. By default, the server that supports OTA should run in the compatible mode. OTA is only applied if the client's request header has a flag set. However, if the server switch on OTA explicitly, all clients must switch on OTA, otherwise connections will be denied.
  3. The authentication method is **HMAC-SHA1** which has wide supports among all major platforms and fairly good speed.
  4. ##TCP
  5. The structure of an OTA-enabled request (unencrypted) is shown below:
  6. ```
  7. +------+---------------------+------------------+-----------+
  8. | ATYP | Destination Address | Destination Port | HMAC-SHA1 |
  9. +------+---------------------+------------------+-----------+
  10. | 1 | Variable | 2 | 10 |
  11. +------+---------------------+------------------+-----------+
  12. ```
  13. ATYP is a 8-bit char where the rightmost four bits, 0b00001111 (0xf), are reserved for address types, the flag bit of OTA is 0b00010000 (0x10). In C/C++, simply check if `ATYP & 0x10 == 1`, then OTA is enabled.
  14. The key of HMAC-SHA1 is (IV + KEY), and the input is the whole header (not including HMAC-SHA1). The output of HMAC-SHA1 is truncated to leftmost 80 bits (10 bytes) according to [RFC 2104](https://tools.ietf.org/html/rfc2104#page-5).
  15. ###Chunk Authentication
  16. The structure of an OTA-enabled chunk (decrypted) of shadowsocks TCP relay is shown below:
  17. ```
  18. +----------+-----------+----------+----
  19. | DATA.LEN | HMAC-SHA1 | DATA | ...
  20. +----------+-----------+----------+----
  21. | 2 | 10 | Variable | ...
  22. +----------+-----------+----------+----
  23. ```
  24. DATA.LEN is a 16-bit big-endian integer indicating the length of DATA.
  25. The input of HMAC-SHA1 is DATA. And the key of HMAC-SHA1 is (IV + Chunk ID) where Chunk ID is an unsigned integer counted per connection from 0. In order to achieve this, both server side and client side need to keep a counter for each TCP connection. Chunk ID must be converted to big-endian before constructing the key of HMAC-SHA1.
  26. For a client, after constructing an OTA-enabled request, the whole chunk is encrypted as a payload then sent to server-side.
  27. Tips:
  28. - The server must check the completeness of a shadowsocks TCP request before verifying HMAC-SHA1 and forwarding.
  29. - The chunk authentication is only applied for the packets sent from client-side shadowsocks.
  30. ##UDP
  31. There is no _session_ in UDP relay, each UDP packet contains both header and data. Therefore, for an OTA-enabled UDP packet, the datagram structure (unencrypted) is slightly different:
  32. ```
  33. +------+---------------------+------------------+----------+-----------+
  34. | ATYP | Destination Address | Destination Port | DATA | HMAC-SHA1 |
  35. +------+---------------------+------------------+----------+-----------+
  36. | 1 | Variable | 2 | Variable | 10 |
  37. +------+---------------------+------------------+----------+-----------+
  38. ```
  39. The key of HMAC-SHA1 is (IV + KEY), and the input is the header plus data.