# AES encryption using a Diffie-Hellman key exchange

I have two systems which need to encrypt their communication by AES-128. The key for the AES encryption should be exchanged with the Diffie-Hellman (DH) algorithm.

Now, I've read about DH and got a lot of question marks over my head. These are my questions:

1. Typically with AES-128, you need a password and a key which will be generated from the password. What exactly will be exchanged with DH, is it the password or the key? In other words, what is the secret that Alice and Bob will calculate?

2. If I use a 1024 bit prime and a 256 bit private secret for DH, the calculated secret will consist of a lot more than the required 128 bit for AES-128. How can I transform the secret to match the required 128 bit? Is there a standard to do it, because the two systems use different programming languages?

You see, there is a lot of confusion. Maybe you could help me and shed some light on it.

-

## migrated from security.stackexchange.comJul 31 '13 at 16:05

This question came from our site for information security professionals.

There is nothing related to passwords in AES. AES uses 128-bit keys, i.e. sequences of 128 bits. How you come up with such a key is out of scope of AES. In some contexts, you want to generate these 128 bits in a deterministic way from a password (and possibly some publicly known contextual data, like a "salt"); this is a job for password hashing. In other contexts, in particular the one you are talking about, there is no password.

In Diffie-Hellman, computations occur modulo a big prime p, and the resulting shared secret is an integer modulo p, i.e. a value ranging from 0 to p-1. This value has some "structure" so you should not truncate it blindly. The "safe" way is to apply a hash function on an encoding of that value, for instance SHA-256. The hash function output is then what should be used as key (with possible truncation to get the proper length; at that point, this is safe). There are standards which describe such a process in full details.

Of course, you are in the process of reinventing your own homemade kind-of-SSL, and that is a thoroughly bad idea in general (unless you are doing it for pedagogical reasons, e.g. as homework). A really secure protocol will need key exchange, proper symmetric encryption, integrity checks and at least one-sided authentication, so you will have to assemble at least three cryptographic algorithm. Every single detail can doom your security, both in the design and in the implementation. This is hard. It took two decades of hard labour, from hundreds of the best cryptographers, to come up with a decently secure version of SSL. Imagining that you could do as well by yourself is preposterous.

So there is a standard, it is called TLS (the "standard" name for SSL). Use that, or be sorry.

-
I don't want to reinvent SSL. The only thing I want is to share my symmetric key properly. I can't use SSL, since one of the machines is an embedded system which does not support SSL. So, if I understood you correctly the simple answers are 1. A 'password' will be exchanged, but it must be encoded with a hash function after calculation. 2. The hashed secret can be just safely truncated to 128 bit. – Neomatik Jul 31 '13 at 14:02
I have, personally, implemented a fully-compliant SSL stack (client and server) which fits in 20 kB of compiled code and 17 kB of RAM. SSL can be small. The point here is that a secure protocol will have to include a lot of SSL-like features, to the point that you cannot really do smaller than a small SSL implementation (unless you don't mind glaring weaknesses). So the sensible thing is to use the standard, i.e. SSL, where all hard details have already been thought out. – Tom Leek Jul 31 '13 at 14:08
1. No, an identical shared secret will be calculated at both sides, not a password. After that you should use a key derivation function to create a key out of the data. In the simplest form this could be a cryptographic hash over the shared secret. 2. You should not simply truncate the shared secret before hashing as you will loose a bit of entropy doing so; the key will not be fully random (it will be almost fully random though). There is no password, a password is a character string, the shared secret will be an integer with a relatively random distribution. – Maarten Bodewes Aug 7 '13 at 20:15

I will try to simplify things:

1. preliminary: When you encrypt data with a cipher, e.g. AES, you provide it with a password. The cipher algorithm takes (internally - you don't need to do anything programmatically) the password and generates a key out of it by applying some cryptographic algorithms to it. The purpose of this key-generation internal phase is to "obfuscate" your password by hashing and to have a proper length of a key to fit the cipher algorithm. That key is then used internally by the cipher to actually encrypt your data.

Now, Alice and Bob need to exchange some shared secret so both can encrypt/decrypt the data with the symmetric cipher e.g. AES. If you use DH algorithm to exchange a shared secret, this secret can be then used as a password for the AES cipher, or be a "seed" password for a stronger password generation algorithm like BPKDF2 (you use the BPKDF2 here as a stand alone program to generate a stronger password - don't get confused here with the "KDF" - "Key Derivation Function" part of the name, since you use it only to generate your strong password, not the "key" for the AES).

2. I don't want to express right now an opinion on the number of bits to use for the DH exchange - Mr. Pornin is the expert here so heed his advice - but to use the DH secret result as a password you can either use the PBKDF2 algorithm and ask it to generate the desired password length, or (a weaker approach compared to PBKDF2) just hash the DH secret with a good hash function e.g. SHA256, and use the left most 32 or 64 hex characters as a password for the AES-128 or the AES-256 algorithm, respectively.

A common hashing function algorithm like SHA256 is available in many programming languages.

-
You might want to get rid of the expression "password" (alphanumerical; low entropy; can be remembered by humans easily). Encrypting data with a symmetric cipher like AES does not start with some kind of "password" or other random "seed", it starts with assuming a uniform random key from the keyspace. There are various ways to get there, but in this case PBKDF2 is not needed at all: There is no need for salting, multiple iterations or key stretching. What is needed is a compression function with images in the full key space. A cryptographic hash does the trick. – tylo Aug 12 '13 at 14:44
@tylo while you come from the cryptographic agorithm point of view, I tried to answer from a application usage point of view. Judging from the question, I take it that the user has a AES encryption application, needs to enter a password, and wonder how to exchange that password with a remote user. I would dare to say that your response, as well as the others here, are too technical for the OP. – Ninveh Aug 12 '13 at 23:15
You might be right. But on the other hand, then this would be a question for security exchange, not crypto. – tylo Aug 13 '13 at 12:03