2

Sorry in advance as I am not very skilled in crypto. I am a software developer trying to create secure applications.

I have implemented a diffie-hellman key exchange between client and server. The library I am using only lets me create a minimum size key of 64 bytes (512 bit). During transport messages will be encrypted with an AES-256 cipher. This takes a maximum key of 32 bytes (256 bit).

Is it safe to use the first 32 bytes of the diffie-hellman generated key or does this create a hole in security?

I may be completely incorrect so please forgive me; AES-256 is a standard widely used encryption algorithm today and using a 32 byte key is secure. I didn't just wan't to the approach that "Because it works it must be secure"

Harvey
  • 121
  • 1
  • 4
  • 3
    Is there a reason you can't use a KDF? Anyway, you really should be using an existing library. It's not enough if you want a secure application to just use Diffie-Hellman and AES. You need to do a lot more. – forest Jul 26 '19 at 09:46
  • 4
    Also, it's 2019. Do not use 512-bit Diffie–Hellman! – yyyyyyy Jul 26 '19 at 09:47
  • I appreciate your thoughts. A few things. I can look into KDF. I have not heard of it yet. DH is handled using the cryptography library. not hand written, just implimented. If DH and AES-256 is really not enough is there a reason why? or an alternative?. I was planning on using 2048-bit DH however I would still only be able to use 32 bytes of it for AES-256 – Harvey Jul 26 '19 at 10:13
  • 3
    @Harvey It's not enough because you should be using a library that handles all of this for you by itself, like libsodium. For example, are you using AEAD? Are you protecting from reflection attacks? What mode of operation are you using? How are you generating the nonce/IV? How is authentication performed? With a library like libsodium, this is all abstracted away from you so you don't have to worry about things lik eusing sequential vs random nonces for GCM (you are using GCM, aren't you?). Don't implement it on your own! – forest Jul 26 '19 at 10:17
  • 2
    @Harvey I'll be honest. I think you shouldn't be doing this. Because you're using the shared secret directly, I take it you don't have a MAC key, which means the encryption will be vulnerable to tampering. Please, unless this is just a toy project to learn a bit more about crypto, don't write your own protocol. – forest Jul 26 '19 at 10:25
  • I did not know about libsodium, Python has a wrapper PyNaCl which looks very useful. I'd like to stress I am not creating my own protocol. nor doing anything more than calling library functions to achieve my end result. Currently I am using cryptography and pycryptodome libraries in order to achieve what I have at the moment. I fully understand that trying to create your own encryption is a silly idea. – Harvey Jul 26 '19 at 10:38
  • 1
    @Harvey But even implementing it is dangerous. Just using existing library functions will open you up to security issues. Are you using an authenticated mode? Do you even know if you are? If not, it's a very severe issue and the crypto libraries won't warn you at all. – forest Jul 26 '19 at 10:41
  • @forest I can happily use PyNaCl for crypto. My operation mode is CBC. The library in CBC mode does not give definition to using a nocne. I am unsure what AEAD is. There is no authentication of an encrypted message. Again I stress I do not intend to implement "on my own" and this is the reason I wanted to be mindful about security before taking the approach of "oh it works so it must be right" as this is not a good attitude to have and there are much smarter people than me in this field. This is the point of asking the question – Harvey Jul 26 '19 at 10:42
  • 3
    @Harvey It's very good to ask the question. My point is that raw crypto libraries are often not very easy to use safely. For example CBC mode is very insecure without an HMAC, and an HMAC requires an extra key. – forest Jul 26 '19 at 10:44

1 Answers1

5

Currently we do not think that 512 bit DH is secure. You can look for more secure parameters (i.e. above 1280 bits at the very least) is secure. Secure key sizes can be found at keylength.com. For DH you can e.g. look at the NIST recommendations for "Discrete Logarithm" (the underlying mathematical problem that is the base of DH-based cryptography).

Using Diffie-Hellman as base for AES-256 is a bit misleading, as it is not likely that your DH provides the same level of security as AES-256. As you can see in the tables DH requires a 15K key size (!!!) to reach the same security level. Claiming a security level of 256 bits would be unfair (but read the next section)


What DH generates is a shared secret. This shared secret has a lot of pseudo-randomness. As such it can be used directly by using the leftmost (or rightmost, but leftmost is more common) bits of the shared secret as a key. More information here (note the author of the question!). This is however not considered good practice, as you preferably do not want to have any bias of bits in the secret (AES) key.

So commonly we use a key based key derivation function (key based KDF or KBKDF) to condense (or extract) the pseudo-randomness of the master secret into one or more keys. That way each bit of the key depends on each and every bit of master secret material and removes any possible bias in the bits of the resulting secret key.

Quite often cryptographic API's offer combined key agreement / key derivation functions where a KDF is already used upon the result. Sometimes that means indicating a hash function, which is then used as (only) primitive within the KDF. The compression functionality within a hash is, as you might imagine, perfect for condensing the pseudo-randomness.

If you do not use a KDF then you might want to use a 256 bit AES key as it will have at least 247 bits of pseudo-randomness, as specified in the answer on my question. A 128 bit key will have less than 128 bits after all.

tadman
  • 103
  • 2
Maarten Bodewes
  • 92,551
  • 13
  • 161
  • 313
  • 3
    This is a direct answer, but I agree with forest: using a ready made, well studied library that offers crypto on a higher level is a better idea than thinking up your own scheme. Even if you do require a very specific scheme, you'd be better off first studying existing ones. – Maarten Bodewes Jul 26 '19 at 10:24
  • 1
    Ugh, forgot about the bias in AES-128 if that was to be used. See? that's how easy it is to make stupid mistakes when creating your own scheme! – Maarten Bodewes Jul 26 '19 at 10:30
  • 1
    This is a well written answer. Clearly describing that you can do it. but shouldn't. A resewn why and what is good practice – Harvey Jul 26 '19 at 10:50