6
$\begingroup$

I noticed that the GO standard library has some really nice functions for performing AES encryption / decryption in various modes. However, I couldn't (yet) find anything for Diffie-Hellman key exchange.

I'm not sure if I should proceed by searching more carefully, switching to a different language with a more extensive crypto library, or trying to implement the key exchange protocol myself.

The protocol "seems" implementable:

  • Alice sends $g^a \mod p$ to Bob
  • Bob sends $g^b \mod p$ to Alice
  • We need to choose $g, a, b, p$ appropriately

But I'd bet that there are a lot of subtleties buried in that "straightforward protocol" (for example, we need some out-of-band mechanism to defend against man in the middle attacks).

Plus, one of the first lessons of crypto is don't implement cryptographic primitives yourself, and I don't know if this warrants an exception to that lesson.

Are developers generally expected to implement Diffie-Hellman key exchange themselves? If so, what are the primitives that I should be using, and where can I find a good reference for some of the subtleties that should be considered?

$\endgroup$
7
  • 1
    $\begingroup$ You should definitely avoid implementing crypto yourself if anyhow possible (nice to have noted that yourself :) Some example subtleties: You need to ensure p is chosen appropriately, you need to ensure a and b are generated sufficiently randomly, you should ensure that the operation is sufficiently fast, you should ensure that an attacker can't deduce your private key from the timing and not to start with the "out of band" methods... $\endgroup$
    – SEJPM
    Commented Mar 8, 2016 at 20:33
  • $\begingroup$ I guess you want to perform some sort of communication. Did you look for a SSL/TLS library for Go? $\endgroup$
    – SEJPM
    Commented Mar 8, 2016 at 20:34
  • $\begingroup$ SEJPM, thanks for the input! I did look at the TLS package, but I'd probably only use SSL/TLS if there are no other options. My main concern here is that I'm implementing something where clients are communicating through an UNtrusted server. Since I'd like to have OTR-like security properties (end-to-end encryption, preservation of forward secrecy even if the server logs all traffic), I'm not sure if TLS alone will be sufficient. $\endgroup$
    – Elliott
    Commented Mar 8, 2016 at 20:40
  • 2
    $\begingroup$ TLS can do that if you use the (EC)DHE cipher suites (and if you connect via the server and not to the server). Additionally there is supplemental crypto code here. If you really want to do (EC)DH, I think you may have to implement it yourself (this should be easier with ECC if you always check if points are on curves, use the library for scalar multiplication and hash the agreed value) or (better) switch to another language. $\endgroup$
    – SEJPM
    Commented Mar 8, 2016 at 21:28
  • $\begingroup$ The latter part of the question is off topic as a link/implementation request. The former is sort of on topic, I think. $\endgroup$
    – otus
    Commented Mar 9, 2016 at 7:35

2 Answers 2

2
$\begingroup$

Look for a 'Key Agreement' functionality (see https://golang.org/src/crypto/tls/key_agreement.go), as many comments above suggested - if you're trying to establish a secure communication channel, the default TLS (SSL) would be good way to go.

$\endgroup$
1
  • $\begingroup$ Thanks, that makes sense. I recently (after hearing from you and SEPJM) found out that TLS is a lot more flexible / extensible than I previously imagined! $\endgroup$
    – Elliott
    Commented Mar 11, 2016 at 18:52
1
$\begingroup$

To find a free implementation of a simple Diffie Hellman can be offered by HEAPS of libraries such as: OpenSSL, NaCl/LibSodium etc etc.

Also many languages offer it in the default apis for example Node.js: https://nodejs.org/api/crypto.html

If a language does not support it by default and its ecosystem does not offer a library from 3rd party you can always do some C/C++ bondage (in order words some bindings) with libraries such as OpenSSL, NaCl/LibSodium etc etc. Just wrap it nicely in your own exposed pass-through api wrapping the libraries functionalities. That approach is recomended for missing or low level functionalities such as group key agreements or a sustom authentication/agreement protocol.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.