Create AES key after ECDH

I use ECDH to have a shared secret between Alice and Bob, which runs on Android and the other on the built-in. I understand that it is best practice that both parties generate an AES key to encrypt messages. Can someone send an example of how both sides Alice and Bob generate the same AES key after they agreed on a shared secret using ECDH?

+1
android encryption aes
source share
2 answers

It is probably best to follow the NIST guidelines for key agreement schemes, for example. using NIST SP 800-56A with recommendations in the Developer's Guide and one of the key derivation methods specified in NIST SP 800-108 . It describes how to convert a secret to bytes, and then one of the KDF can be used to convert to (multiple) keys.

Please note that key output is in the lightweight Bouncy Castle API from 1.50 and therefore must also be present in Spongy Castle . The most common NIST algorithm is in org.bouncycastle.crypto.generators.KDFCounterBytesGenerator . You can simply give it HMAC (e.g. HMAC SHA1) in the constructor and org.bouncycastle.crypto.params.KDFCounterParameters during initialization.

Note that this adheres to better cryptographic practices than the Perseid response, but it can be much more difficult to understand / implement.

+3
source share

After starting ECDH successfully, you have the same group element at both ends. Now you need to define a uniform encoding of the elements in the form of a byte array / octet. Using a hash function (e.g. SHA256), you can reduce the array to a 256-bit value. If you need to get multiple keys, you can add an array of bytes with different constants for each key before hashing them.

A simple example: suppose your point is an elliptical curve (51357992175.89175716892). You can represent this curve point as the string "(51357992175,89175716892)". For different keys, you can add some string constants, such as "MacKey" or "EncryptionKey". To get some original byte values, you can encode these strings with utf8. In general, the keys will be:

 macKey = sha256("(51357992175,89175716892)MacKey".getBytes("UTF-8")) encryptionKey = sha256("(51357992175,89175716892)EncryptionKey".getBytes("UTF-8")) 

Edit , in connection with your question related to comments ("In my case, I have one server and many clients that approach it several times a day, and each time I need to have a different AES key based on a shared secret.") About how to create a large number of keys, one for each communication event:

You find yourself in a rather complicated area of ​​cryptographic protocol development. Think about these questions:

  • How do you guarantee that a different key is created for each new message you send? Standard solutions would be to use a counter or a random number like nonce (a number used once), each of which has its own problems. (Counter: it should be strictly monotonous even in the event of an application crash or backup. Random: it should be large enough to prevent accidental collisions - something like 256 bits would be enough - and you should constantly trust the random number generator to be good .)
  • How do you prevent replay of messages attacking the receiving side? You can track all unused (with intensive storage of data) or, possibly, use a monotonous counter in case nonce is monotonous and rejects any message that has nonce less than or equal to a monotonous counter.
  • How do you react to message delay, reordering or selective blocking of messages? In many cases, it is important to be able to notice these events, and you must decide what to do then. (For example, TLS requires interactive interactions between the two parties and terminates the connection if something fails but cannot detect delays (unless shameful heart contractions are now used to connect the connection).

With an extended warning behind us, back to your question:. For each new key, you can use nonce (the number used once), which is included in the derivation of keys to create a unique key for the target. I am basically rebuilding something similar to "5.1 KDF in Counter Mode" from the NIST SP 800-108 , which was already mentioned, with a clear text component. At this point, I would recommend reading it in any way, since it is not so long and contains a lot of background considerations. In addition, you should limit the use of the key as close as possible. For example, on the server side, use:

 macKey = sha256(sha256("(51357992175,89175716892); MacKey; ServerToClient; 2755".getBytes("UTF-8"))) 

for the 2755th key generated for the purpose of authenticating the message to communicate with the server to the client. You can see the following components: shared secret (elliptic curve point), key assignment (mac), communication direction, nonce counter. I also use double hashing to prevent any extension of the hash length; HMAC would be just as good here. Nonce itself can and should in some cases be published with the message. By itself, it does not contain any confidential information.

+2
source share

All Articles