Re:Secure channels over TCP/IP
by agwa on Tuesday July 07, 2015 @09:42PM
(#9849293)
You wouldn't want to use this. The key exchange is vulnerable to replay and identity misbinding attacks. To fix the replay attack, you also need to sign a nonce from the peer (or its ephemeral public key) to prove that the message is fresh. To fix the identity misbinding attack, you also need to sign the identity of the peer. Then it's probably secure, but the protocol would lack identity hiding. You really want a key exchange protocol like SIGMA, which is secure and provides identity hiding.
As you can see, this stuff is hard and you really shouldn't be designing your own. CurveZMQ (basically, DJB's CurveCP over TCP) is probably a better choice if you want a NaCl-based secure channel. CurveZMQ also happens to be pretty well documented if you want to learn about what it takes to design a secure protocol: http://curvezmq.org/page:read-the-docs
Re:Secure channels over TCP/IP
by agwa on Saturday July 11, 2015 @12:24PM
(#9870365)
He found problems with the identity binding where if even a short-term key was compromised, it would allow impersonation attacks in the future[1]. That's a poor way to handle failure (and it's fixed in CurveZMQ with the minor changes he proposed) but it requires a key compromise to exploit so it's not as bad as a straight-up misbinding attack which any MitM can exploit.
Re:Secure channels over TCP/IP
by diafygi on Tuesday July 07, 2015 @07:45PM
(#9848909)
What advantage does this have over spiped[1]? Since there's not really a good way to distribute public keys, you really need to just put them on a thumb drive and walk them over to the person that wants them. And if you're doing that, you might as well give the person a shared secret.
Re:Secure channels over TCP/IP
by jallmann on Tuesday July 07, 2015 @07:14PM
(#9848767)
The public key operations during setup are clearly useful for authentication against a possibly untrusted peer. What mechanism is used for key distribution? Revocation? Is the main advantage over TLS in its use of a limited set of cryptographic primitives (as provided by NaCl), at the expense of flexibility? Any other advantages, such as decreased setup time? What about upgradeability -- does the protocol have the ability to roll in additional keys/exchange algos or ciphers as better ones become available?
Of course, the more of these features you add, the closer you get to TLS. That being said, without these features (eg, if you need to basically upgrade your whole fleet just to update to a newer NaCl or to add keys as opposed to using a signed certificate mechanism), the advantage starts shifting towards even simpler approaches, such as spiped, which omits all the public-key ceremony in favor of a shared secret key.
Re:Secure channels over TCP/IP
by cespare on Tuesday July 07, 2015 @06:46PM
(#9848612)
Interesting. A couple of questions that come to mind:
- Any rough benchmarks vs. TLS? Or even just back-of-the-envelope math/reasoning behind the claim in the opening paragraph: "without the overhead of TLS".
- Instead of generating 24 PRNG bytes for each message to use as the NaCl nonce, why not use the sequence number each message is assigned anyway?
Re:Secure channels over TCP/IP
by 0xEA on Tuesday July 07, 2015 @07:15PM
(#9848774)
nacl says that for security each nonce/key pair must be unique for each message. If you send a "HELO" message, for example first, you've made it possible to build a pretty simple rainbow table if nonce just starts at 0 or 1. That said, it would seem that the first nonce being random and then incremented would likely work well.
Re:Secure channels over TCP/IP
by agwa on Tuesday July 07, 2015 @09:53PM
(#9849325)
A rainbow table? The key space is 2^256. If you're talking about building a table containing the ciphertext of "HELO" with all possible keys, that's totally infeasible. As you correctly state, NaCl requires each nonce/key pair to be unique. If you start the nonce at 0 for a given key and increment it for each message, as is commonly done, that satisfies the requirement and is secure.
Re:Secure channels over TCP/IP
by mborch on Wednesday July 08, 2015 @04:29AM
(#9850447)
"On our production frontend machines, SSL/TLS accounts for less than 1% of the CPU load, less than 10 KB of memory per connection and less than 2% of network overhead. Many people believe that SSL/TLS takes a lot of CPU time and we hope the preceding numbers will help to dispel that." - Adam Langley, Google.
Re:Secure channels over TCP/IP
by slasaus on Wednesday July 08, 2015 @08:15AM
(#9851038)
I assume your point is about the first sentence of the article "This library was born out of a need to set up a secure channel over a TCP/IP network without the overhead of TLS.", but I interpreted this not in terms of performance, but in terms of lines of source code. OpenSSL in particular is pretty bloated [1].
Re:Secure channels over TCP/IP
by doomrobo on Tuesday July 07, 2015 @07:55PM
(#9848939)
The key exchange high-level overview looks like it has some typos.
Firstly, the <sub></sub> is being escaped instead of being interpreted as a tag. Also you say that the client and server make a keypair and create a tuple k_(pub,1) || k_(pub,2) || sig. Why would one participant have 2 pubkeys? If you meant it to be one public and one private, why would it include a private key? Is it actually that the client makes k_(pub,1) || client_sig and the server makes k_(pub,2) || server_sig? Also later you reference k_(peer,1) and k_(priv,1) which weren't mentioned previously at any point.
Sorry if I'm misunderstanding anything. I'm gonna read through the Go code to see if I can understand better, this looks really interesting!
Re:Secure channels over TCP/IP
by doomrobo on Tuesday July 07, 2015 @08:21PM
(#9849022)
Update
Looking at the source, it seems like the initial key exchange keys are sent as a k_(pub,x) || sig tuple where x is 1 for the sender and 2 for the receiver. Similarly, it looks like the shared keys are derived from subslices of k_(pub,x) and k_(priv,3-x).
Is there a particular reason there isn't a single read/write symmetric key that's derived from the entirety of the public and private keys?
Re:Secure channels over TCP/IP
by tptacek on Tuesday July 07, 2015 @07:11PM
(#9848751)
Probably not, because messages are authenticated cryptographically, and the lengths are validated before being passed to libsodium. You can't truncate an authenticated message.
See the following presentation, which presents insecure key exchange protocols (the key exchange from the article is on page 4) while building up to SIGMA: https://www.ietf.org/proceedings/52/slides/ipsec-9.pdf
As you can see, this stuff is hard and you really shouldn't be designing your own. CurveZMQ (basically, DJB's CurveCP over TCP) is probably a better choice if you want a NaCl-based secure channel. CurveZMQ also happens to be pretty well documented if you want to learn about what it takes to design a secure protocol: http://curvezmq.org/page:read-the-docs
[1] https://codesinchaos.wordpress.com/2012/09/09/curvecp-1/
[1]: https://www.tarsnap.com/spiped.html
Of course, the more of these features you add, the closer you get to TLS. That being said, without these features (eg, if you need to basically upgrade your whole fleet just to update to a newer NaCl or to add keys as opposed to using a signed certificate mechanism), the advantage starts shifting towards even simpler approaches, such as spiped, which omits all the public-key ceremony in favor of a shared secret key.
- Any rough benchmarks vs. TLS? Or even just back-of-the-envelope math/reasoning behind the claim in the opening paragraph: "without the overhead of TLS".
- Instead of generating 24 PRNG bytes for each message to use as the NaCl nonce, why not use the sequence number each message is assigned anyway?
[1] http://www.zdnet.com/article/openbsd-forks-prunes-fixes-open...
Firstly, the <sub></sub> is being escaped instead of being interpreted as a tag. Also you say that the client and server make a keypair and create a tuple k_(pub,1) || k_(pub,2) || sig. Why would one participant have 2 pubkeys? If you meant it to be one public and one private, why would it include a private key? Is it actually that the client makes k_(pub,1) || client_sig and the server makes k_(pub,2) || server_sig? Also later you reference k_(peer,1) and k_(priv,1) which weren't mentioned previously at any point.
Sorry if I'm misunderstanding anything. I'm gonna read through the Go code to see if I can understand better, this looks really interesting!
Looking at the source, it seems like the initial key exchange keys are sent as a k_(pub,x) || sig tuple where x is 1 for the sender and 2 for the receiver. Similarly, it looks like the shared keys are derived from subslices of k_(pub,x) and k_(priv,3-x).
Is there a particular reason there isn't a single read/write symmetric key that's derived from the entirety of the public and private keys?