The replay Filippo is talking about is in the context of a single key. The remote side simply reads the nonce || message off the wire and aead.Opens it, without regard to whether or not that nonce has been used before to decrypt a previous message.
Here's an example, if you do
Write("Hello")
Write(" the password is ")
Write("password")
then without a key I can make you or your peer read "Hello the password is Hello" (or "HelloHelloHello" or any composition of those messages).No Noise protocol would allow that.
(To say nothing of: this uses signatures, and Noise does not).
I don't remember what it is specifically about it, I just remember the document being a pain to read; a bit like the original Paxos paper in that regard.
If you want to secure a stream with asymmetric cryptography and don't need all the bells and whistles of TLS, what's the correct way to do it? Noise? Is there nothing simpler?
As far as alternatives go, Noise Pipes[0] never took off, but feel like they'd be well suited to this task.
Edit: Here's that classic: https://web.archive.org/web/20090606064715/http://www.matasa...
https://github.com/sillystack/api/blob/main/transport/transp...
I'm not going to make any security claims as of now (it's almost certainly broken) but it uses the Noise IK handshake.
Long term I think NoiseSocket would be a good way to go https://noisesocket.org/post/1/ but perhaps in service-to-service use cases ciphersuite negotiation can be simplified.
A single symmetric key is derived for both directions, and there is no checking of nonces, so as far as I can tell any message can be dropped, reordered, or replayed in both directions. (Including replaying message from A to B as if they were from B to A.) This is a bit like using ECB and likely to lead to fun application-specific attacks like [0].
This is very much rolling your own crypto, in a dangerous way. I am on the record as being "against" the "don't roll your own crypto" refrain [1], but mostly because it doesn't work: it should discourage people from publishing hand-rolled protocols such as this, but instead people think it means "don't roll your own primitives" and accept any use of "Ed25519/X25519" as probably secure.
Please read about the Noise framework [2] to get an idea of how much nuance there is to this, and consider using a Go implementation of it [3] instead.
P.S. This kind of issue is also why I maintain that NaCl is not a high-level scheme [4]: this could have used NaCl and have the exact same issues. libsodium has a couple slightly higher-level APIs that could have helped, secretstream [5] and kx [6], but again please use Noise.
[0] https://cryptopals.com/sets/2/challenges/13
[1] https://securitycryptographywhatever.buzzsprout.com/1822302/...
[2] https://noiseprotocol.org/noise.html
[3] https://github.com/flynn/noise
[4] https://words.filippo.io/dispatches/nacl-api/
[5] https://libsodium.gitbook.io/doc/secret-key_cryptography/sec...
[6] https://libsodium.gitbook.io/doc/key_exchange