Open brannondorsey opened 5 years ago
Some points from our conversation as I remember, in case others have thoughts...
One downside to this approach to replay prevention is that it depends on "network conditions" -- if a message is delayed for some reason (eg delayed send, slow propagation across a repeater network, delayed processing, or unsynchronized sender/receiver clocks), then a valid message may be invalidated by a client.
A deterministic approach might be inclusion of a nonce field that can be used by clients interested in recency guarantees. A sender generates a nonce, then receivers can use that nonce to prove their response is not a replay (at least to the sender -- others can not necessarily trust the recency of another sender's nonce). This of course has downsides, especially if I want to reply to multiple messages at once with recency proofs for multiple senders.
Can't the signature of the most recent (or "deepest") message work as a nonce?
That's an interesting idea, but it doesn't work in this case as the signatures generated via elliptic.js are deterministic.
const EC = require('elliptic').ec;
const ec = new EC('p192');
const key = ec.genKeyPair();
const msgHash = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
const one = key.sign(msgHash);
const two = key.sign(msgHash);
one
// Signature {
// r: <BN: fa6c7741d8bd83e7088d27285dbf42b097161020d76b800a>,
// s: <BN: c0cabfec613f049bc100bb6ec724ea9c5a8c35995e2ec3cd>,
// recoveryParam: 0 }
two
// Signature {
// r: <BN: fa6c7741d8bd83e7088d27285dbf42b097161020d76b800a>,
// s: <BN: c0cabfec613f049bc100bb6ec724ea9c5a8c35995e2ec3cd>,
// recoveryParam: 0 }
We don't want two messages by the same sender containing the text "yes" to have the same message nonce (if we go with a nonce-related solution). If the message signatures contain the timestamp, that becomes less of a problem, but still would prevent two different messages with the same contents sent during the same second from being differentiated.
All this said, I do think nonces may be useful in the protocol down the road. Even as a solution to the replay attack problem should one choose not to use timestamps. The way I see it, the protocol could have support for both, and the client/user could pick which method (timestamp or nonce) to use.
A deterministic signature is a good thing. My suggestion is to include the previous ("deepest") message in the message body and sign that. A sequence of messages will build up and if a replay happens it shows up as a node earlier in the sequence.
I think this approach requires a reliable transport and wouldn't work with message loss.
I would have to agree. I favor a solution that doesn't require a reliable connection. Consider a scenario where a station broadcasts a weather beacon each hour. The protocol should provide a mechanism to protect against replay attacks even when the communication is entirely one way.
I used to launch weather balloons! :)
Not sure why reliability is needed, was thinking reliability would be built on top of that, something like a query for a signature you heard referenced but don’t have.
Right on :balloon:
My suggestion is to include the previous ("deepest") message in the message body and sign that. A sequence of messages will build up and if a replay happens it shows up as a node earlier in the sequence.
In my mind anything that builds on sequence starts to fall apart with unreliable connections. I'm also hesitant to include entire signatures or hashes of past messages as that could dramatically increase the payload size. A solution like you mentioned could be implemented on top of the protocol though.
I'm leaning towards implementing this in the next version of the Chattervox protocol. Any objections or comments? Specifically, I'm planning on including the timestamp field as a 32-bit unsigned integer that represents a time value in seconds since Midnight Jan 1, 2000.
👍
Proposal
Add a timestamp field to the chattervox packet to protect against replay attacks. Initially proposed here.
Details
Protocol v1 supports cryptographic message signatures but provides no mechanism to protect against the replay of signed messages by parties other than the original sender/signer of a message.
From https://github.com/brannondorsey/chattervox/issues/10:
The goal of this RFC is to add protocol-level protection from replay attacks using timestamps. Timestamps will be included in packets, however, it is up to the chattervox client software to choose how use them.
Considerations
Protocol Changes
Implementation Notes
The addition of a timestamp field in the chatttervox protocol doesn't itself protect against replay attacks but it provides a mechanism for client software to do so. It's up to the chattervox client to use a computer's clock to compare the timestamp value in a packet to the time a message was received. If the distance between these two values is greater than some threshold then the message is likely being replayed and should be ignored by the client or alert the user of the attack. It is up to the client software to implement this comparison check as well as to define an appropriate threshold. A threshold should be large enough that it allows messages to be digipeated over a busy channel or across several digipeater hops but small enough that it doesn't leave the receiver vulnerable to replay attacks for a prolonged period of time. A threshold value of 5 minutes would allow the replay of messages within a 5 minute window. Transmission time should also be factored into the threshold value as a message may take a second or longer to transmit via 300 or 1200 baud. The chattervox typescript client will likely set this threshold at 30 seconds for initial testing.
Open Questions
Updates