Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Sending data from server -> client with NOISE_N is unsafe #45
The documentation for
// Done! session_kp.tx is the key for sending data to the server, // and session_kp.rx is the key for receiving data from the server.
// Done! session_kp.tx is the key for sending data to the client, // and session_kp.rx is the key for receiving data from the client. // The session keys are the same as those computed by the client, but swapped.
The type signatures of
However, the Noise specification's description of one-way handshake patterns strongly warns against this:
The rule referred to in 7.3 is:
In other words, the server sending a message back to the client using one of the computed session keys is bad because there's no random contribution on its part to the generation of the session keys. An active attacker could supply the same ephemeral key multiple times, resulting in key reuse. To do this safely, you'd instead want an interactive NOISE_NK handshake.
Please let me know if I've misinterpreted something here. Otherwise, the documentation should surely be updated, and (if changing the type signature is acceptable)
While Noise strives to provide PFS everywhere, this protocol is not "unsafe". It is equivalent to the key exchange mechanism present in NaCl/libsodium.
Keys are not reused. This specific implementation forces the client to generate a new key pair for each exchange. The secret key is immediately discarded.
An active attacker can send a previously observed public key, but a reused session key is harmless as long as a nonce is not reused with different message as well. And this is something that hydrogen prevents by design. There are no ways for applications to provide their own nonce to bypass this.
Of course, ephemeral keys should be used whenever possible.
Thanks for the explanation. So the server's
Correct. You lose forward secrecy, which is impossible to achieve with a single RTT.
However, even non-ephemeral server static keys are not designed to be used forever. The current best practices go completely against this.
Let's Encrypt certificates, for example, can only be used for 90 days. Protocols such as DNSCrypt require certificates to be only valid for up to 24 hours.
These certificates are signed with a long-term key, and can be rotated frequently. This can have performance tradeoffs, but clients can fetch and verify new public keys as needed.
If a server secret key is leaked, only the very recent session keys can be recovered, so you still get some forward secrecy.