add protocol steps for the server

This commit is contained in:
Adrien Marquès 2018-09-10 14:38:28 +02:00
parent a33a3dba72
commit df7e20c855
1 changed files with 25 additions and 159 deletions

View File

@ -128,7 +128,7 @@ Send $x_1$ and $x_2$.
|:--------:|:------|
| `1` | $t\_c = \mid \frac{t\_{now}}{W}\mid$ |
| `2` | $x\_1 = h^{n}(K) \oplus h(t\_c)$ |
| `3` | Generate $(K',n',s')$ until <br><ul><li>$[(h^n(K) \oplus h^{n'}(K')) \And 1] \ \mathbb{Z}\_{(2)} = t\_c \ \mathbb{Z}\_{(2)}$</li></ul> |
| `3` | Generate $(K',n',s')$ until <br><ul><li>$[(h^n(K) \oplus h^{n'}(K')) \And 1] \ \mathbb{Z}\_{(2)} = m\_c$</li><li>$[(h^N(K) \oplus h^{n'}(K')) \And 11110000] \ \mathbb{Z}\_{(3)} = 1$</li></ul> |
| `4` | $x\_2 = h^{n'}(K') \oplus h(t\_c)$ |
Send $x_1$ and $x_2$.
@ -145,174 +145,40 @@ This protocol is processed when the server sends the 2 hashes $(y_1, y_2)$ to th
| `4` | $T = x\_1 \oplus h(t'\_s)$
| `5` | Find $N \in [min ; n-min[,\ h^{N}(K) = T$.
| `6` | $x\_1 = h^N(K) \oplus h(t\_c)$
| `7` | Generate $(K',n',s')$ until :<br><ul><li>$[(h^N(K) \oplus h^{n'}(K')) \And 1] \ \mathbb{Z}\_{(2)} = t\_c \ \mathbb{Z}\_{(2)} $</li><li>$[(h^N(K) \oplus h^{n'}(K')) \And 11110000] \ \mathbb{Z}\_{(3)} = 2$</li></ul> |
| `7` | Generate $(K',n',s')$ until :<br><ul><li>$[(h^N(K) \oplus h^{n'}(K')) \And 1] \ \mathbb{Z}\_{(2)} = m\_c$</li><li>$[(h^N(K) \oplus h^{n'}(K')) \And 11110000] \ \mathbb{Z}\_{(3)} = 2$</li></ul> |
| `8` | $x\_2 = h^{n'}(K') \oplus h(t\_c)$ |
Send $x_1$ and $x_2$.
## blablabla
## 2. Server management
##### Check a token
When receiving a pair of hashes $(x_1, x_2)$, the server has to :
1. Unscramble the request using the time-scrambling algorithm
2. Check the token held into $x_1$ :
- `VALID` $\rightarrow$ authenticated : store the token held into $x_2$, forward request to the logic unit
- `INVALID` $\rightarrow$ not authenticated : send the challenge hashes $(y_1, y_2)$.
When the client sends its next token $h^{n-1}(K)$, the server has to <u>hash</u> it and compare it with the last token $T$. In fact, tokens are generated according to the following property :
$$h(h^{n-1}) = h^n(K)$$
#### 1. Unscramble the request
*In other words, each token is the hash of the next one.*
| Step | Calculation |
|:--------:|:------|
| `1` | $t\_s = \mid \frac{t\_{now}}{W}\mid, m\_s = t\_s \ \mathbb{Z}\_{(2)}$ |
| `2` | $m\_c = x\_1 \oplus x\_2$ |
| `3` | $t'\_c = t\_s - \parallel m_c - m_s \parallel$ |
| `4` | $t\_1 = x\_1 \oplus h(t'\_c)$ |
| `5` | $t\_2 = x\_2 \oplus h(t'\_c)$ |
| `6` | Token is valid if $h(t_1) = T$ |
Because of the main property of cryptographic hash functions, the original data is *cryprographically hard* to find from its *digest* (*i.e. the hashed data*). Since the next token is always the digest of the previous one (and not the opposite), an attacker has no clue about the next token.
#### 2. Invalid request management
**Limitations** : <span style='color:#f01800;'>It seams obvious that there is weaknesses due to hashing recursively a single data, but I do not know if such attack is known or even works.</span>
##### Time Scrambling algorithm
In order for the requests/responses to be only valid a few seconds in time, the tokens are scrambled using a [one-time pad](https://en.wikipedia.org/wiki/One-time_pad).
The sender processes the data as follows:
| Step | Description | Formula |
|:----:|:-----------|:-------|
| 1 | Process the sender's time id | $t\_s = \mid \frac{t_{now}^s}{W} \mid $ |
| 2 | process the sender's time parity | $ m_s = t_s \mod 2$ |
| 3 | Send the time parity | $ Send\ m_s$ |
The receiver has to guess $t_s$ with the following steps:
| Step | Description | Formula |
|:----:|:-----------|:-------|
| 1 | receive the sender's time parity | $Receive \ m_s$ |
| 2 | process the receiver's time id | $t\_r = \mid \frac{t_{now}^r}{W} \mid $ |
| 3 | process the receiver's time parity | $m_r = t_r \mod 2$ |
| 4 | Try to guess the sender's time id | $t'_s2 = t_r - \parallel m_s - m_r \parallel $ |
As a result, the receiver will only be able to retrieve the sender's time id if the reception time is at most $W$ seconds after the sending time :
$$t\_{now}^r \in [t\_{now}^s ; t\_{now}^s + W] \Longrightarrow t\_s = t'_s2$$
In practice, the time id is **hashed** and used to achieve a [one-time pad](https://en.wikipedia.org/wiki/One-time_pad) with the token. Because they both result from the same hash function their sizes are the same.
As a result from the sent token $x_1 = token \oplus h(t_s)$, it is impossible to guess neither the token nor $h(t_s)$ without the other.
**Explanation**
* The time id corresponds to the index of the time slice where slices are $W$ seconds wide. By dividing the time in slices of $W$ seconds, if we process the same calculation at an interval of $W$ or less seconds, we will have either the same result or a result greater by 1.
* The time id parity $m_s$ allows us to adjust the receiver's time id $t_r$ when it receives the request. This difference of 1 second is caused by the division of time in slices, the precision is also divided by $W$.
- $t\_{now}\mod W = 0 \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now+(W-1)}}{W} \mid $; no need for adjustment
- $t\_{now}\mod W = 1 \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now+(W-1)}}{W} \mid + 1 $; need to subtract $1$
- $t\_{now}\mod W = 2 \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now+(W-1)}}{W} \mid + 1 $; need to subtract $1$
- $...$
- $t\_{now}\mod W = (W-1) \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now}+(W-1)}{W} \mid + 1 $; need to subtract $1$
## Protocol properties
##### (1) Token Chain
As a result, <u>each token is the digest* of its predecessor.</u>
>_* : the output of the hash function._
This property allows the server to easily check if a token is valid by comparing it with the previous one $T$. It just has to check if the digest of the token is equal to the previous one.
As a result, <u>each token is bound to the previous one</u>. If a request fails (*e.g. network issue*) and a token is lost, the next one won't be valid.
When receiving an invalid token, the server may sent back to the client a challenge to get the authentication back. This challenge is formed by 2 hashes $(y_1, y_2)$.
##### (2) Time Limitation
Any request received more than $W$ seconds after being sent is invalidated by the server. It protects against manual, slow and process-intensive request forgery. Also a same token is *never* observed over the network.
##### (3) Token unicity
The clients never sends a token more than once. It avoids attackers to reuse tokens. Note that usually the client <u>must not generate</u> a same token twice. The keyset $(K, n, s)$ must never be used twice to generate tokens.
##### (4) One-way Hash Chain
For a given key, <u>every token sent has a lower nonce</u> $n$ than every other that has already been sent. In that way it gives no clue about the next tokens to be used.
##### Constraints
- The server must be able to recover the token if the data is received within the time window.
- If the window expired, the token must be invalidated by the server.
- The server must be able to validate a token if it holds the previous one.
- The server must invalidate a token if it has not the previous one.
- The client must be able to recover the authentication with a challenge.
### Limitations
- If an arbitrary catches, then blocks a request and sends it afterwards, it will be authenticated. This case is equivalent to being the client (with all secret variables), which can *never* occur if you use TLS. Notice that you won't be able to extract anything from the token anyway.
- With requests meta data (*e.g. HTTP headers containing the date*), an attacker knowing $W$ can forge the time hash $h(t_C)$ and be able to recover the private key $K$ by processing a simple *XOR* on the public token. Because the cyclic-hash algorithm generates a unique pseudo-random token from $K$ for each request, this case does not give the attacker any clue about the next token to be sent.
## Protocol definition
Each request will hold a <u>pair of tokens</u> $(x_1, x_2)$. If the server's check fails (*i.e. the client is not authenticated*), it will send back to the client a <u>pair of tokens</u> $(y_1, y_2)$ for resynchronization purposes.
Each token has a size defined by the *hash function*, which is `sha512` for this specification ; the size is then 512 bits.
> For readability purposes, the tokens are sent as their hexadecimal representation ; each token is then a string of 128 characters.
### 1. Send the request
This case is the default where $i$ is far from $1$ so there is no key generation or synchronization to do.
| Step | Description | Formula |
|:----:|-------------|:--------|
| `c1` | Decrement the shifting nonce | $i = i - 1$ |
| `c2` | Calculate the one-time token | $T_c = h^{i}(K)$ |
| `c3` | Get the current time id | $t\_c =\ \mid \frac{t\_{now}}{W} \mid$ |
| `c4` | Calculate the parity of $t_c$ | $m_c = t_c \mod 2$ |
| `c5` | Calculate the time hash $h_{t_c}$ | $h_{t_c} = h(t_c)$ |
| `c6` | Calculate $x_1$, the scrambled *request token* | $x\_1 = T\_c \oplus h\_{t\_c}$ |
| `c7` | Calculate $x_2$, the scrambled *next token* | $x_2 = x_1 \oplus m_c$ |
**Security** : We process a one-time pad between $T_c$ and $h_{t_c}$ it is crucial that both values have the same size of $L$ bits. It makes $T_c$ impossible to extract without having the value $h_{t_c}$, this property applies in both ways.
**Short formulas**
| Field | Short formula |
| :-----------: | ------------------------------------------------ |
| $t_c$ | $\mid\frac{t_{now}}{W}\mid$ |
| $x_1$ | $h^{i}(K) \oplus h(t_c)$ |
| $x_2$ | $x_1 \oplus (t_c \mod 2)$ |
Send $(x_1, x_2)$.
### 2. Receive the request
The server receives $(x_1, x_2)$. It does have to :
1. Guess the client's time id to un-scramble the token
2. Check the token
| Step | Description | Formula |
|:----:|-------------|:--------|
| `s1` | Extract the client's time parity | $m_c = x_1 \oplus x_2$ |
| `s2` | Get the current time id | $t\_s =\ \mid \frac{t_{now}}{W} \mid$ |
| `s3` | Calculate the parity of $t_s$ | $m_s = t_s \mod 2$ |
| `s4` | Guess the client's time id | $t'_c = t_s - \parallel m_s - m_c \parallel$ |
| `s5` | Calculate the time hash $h_{t'_c}$ | $h_{t'_c} = h(t'_c)$ |
| `s6` | Extract the token $T'_c$ | $T'\_c = x_1 \oplus h\_{t'\_c}$ |
| `s7` | Extract the next token $T_{next}$ | $T\_{next} = x\_2 \oplus m\_c \oplus h\_{t'\_c}$ |
| `s8` | Check the token | $h(T'\_c) = T \Longrightarrow T = T_{next}$ |
If the token is valid on step `s8`, the next validation token $T_{next}$ is stored and the request can be processed by the server. If the token mismatches, the recovery mode is enabled.
**Short formulas**
The whole unscrambling process can be shortened into the following formula resulting in $0$ if the client is authenticated.
$$x\_1 \oplus h(\mid \frac{t\_{now}}{W}\mid - \parallel (x\_1 \oplus x\_2) - (\mid \frac{t\_{now}}{W}\mid \mod 2) \parallel) \oplus T$$
| Step | Description | Formula |
|:----:|-------------|:--------|
| `rs1` | Get the current time id | $t\_s = \mid \frac{t\_{now}}{W} \mid$ |
| `rs2` | Calculate the parity of $t_s$ | $m_s = t_s \mod 2$ |
| `rs3` | Calculate the time hash $h_{t_s}$ | $h_{t_s} = h(t_s)$ |
| `rs4` | Calculate $y_1$, the recovery hash | $y\_1 = T \oplus h\_{t_s}$ |
| `rs5` | Calculate $y_2$, used for parity | $y_2 = y_1 \oplus m_s$ |
Send $(y_1, y_2)$.
| Step | Calculation |
|:--------:|:------|
| `1` | $t\_s = \mid \frac{t\_{now}}{W}\mid$ |
| `2` | $y\_1 = T \oplus h(t\_c)$ |
| `3` | $y\_2 = y\_1 \oplus (t\_c \ \mathbb{Z}\_{(2)})$ |
Send $y_1$ and $y_2$.