# Public Key Encryption using ECDHE and AES-GCM

Using a text book example, Alice and Bob want to communicate securely using encrypted messages over an insecure channel (the Internet). Alice and Bob have decided to use ECDH (using ephemeral keys generated per session) and start off by each generating a public/private key pair using Curve P-256 - using SHA1PRNG for randomness. Alice sends Bob her public key and Bob generates a secret key using Alice's public key and his private key. Alice does the same using Bob's public key and her private one.

Eve who is potentially sitting in the middle isn't able to solve the discrete logarithm problem that EC requires so isn't able to compute the secret key. If Eve was actually sitting in the middle at the right time she could have sent Alice and Bob her public key instead. I'm not sure if ECDSA plays a part here, but I have assumed that Alice and Bob would verify they are talking to each other by comparing a fingerprint of their public key through another method. Alice and Bob now have the same 256 bit secret key that they can use for symmetric AES-GCM encryption.

Question 1 - AES-128 requires a 128 bit key and AES-256 recommends a stronger ECDH Curve than P-256 - this means the secret key generated by ECDH is always going to be longer than the encryption algorithm requires. I assume the recommended approach is to use a KDF function like HKDF, but what is the security implication of taking an SHA-256 hash and using it directly for AES-256 or truncating it for AES-128 (Alice and Bob are using Java which doesn't have a native implementation of HKDF and I don't think it is a good idea to try and write your own).

Using an approved method they manage to both derive the same 128 bit encryption key. Alice starts by sending a message to Bob - she generates a 96 bit random IV (she confirms she will never use the same IV with the same key again). She specifies an Authentication Tag length of 128 bits and encrypts the message (she doesn't include any additional authenticated data). She prefixes the IV to the ciphertext and sends to Bob. Bob then recovers the IV and decrypts the message - he knows the message hasn't been modified otherwise the Authentication Tag would be incorrect.

Question 2 - What advantage does ECDSA provide in this scenario or am I mixing things up? Assuming Alice and Bob have verified the public key fingerprints belong to each other, only Bob is in possession of his private key (stored in memory for the duration of the session) - Eve is unable to encrypt a message using the correct secret key because she doesn't have the required private key? For Alice to be able to decrypt the message it must have been encrypted by Bob.

• I suppose it is infeasible for Alice and Bob to verify the fingerprint of a public key every time they initiate a session. Do I assume the correct approach is for Alice and Bob to both generate a static ECDSA key pair - they send the public half to each other and verify the fingerprints offline? They then use their ECDSA private key to sign the ECDH public key before sending. The ECDH public key is then verified using the pre-verified ECDSA public key and authenticity is confirmed. Alice and Bob should both store their ECDSA private key using strong symmetric encryption on disk. – chrixm Nov 4 '15 at 8:19

I assume the recommended approach is to use a KDF function like HKDF, but what is the security implication of taking an SHA-256 hash and using it directly for AES-256 or truncating it for AES-128 (Alice and Bob are using Java which doesn't have a native implementation of HKDF and I don't think it is a good idea to try and write your own).

HKDF(-Expand) is easy to implement if you have access to HMAC, since for short keys it is just HMAC(s, 0x01) with s the shared secret; an optional context string can be prepended to the 1-byte. However, just a hash is fine as well.

What advantage does ECDSA provide in this scenario or am I mixing things up?

If you only need to guarantee privacy and authenticity, there is no need for adding ECDSA into the mix. AES-GCM with the shared secret from the ECDH-exchange is sufficient. However, there are two other scenarios that may make ECDSA useful here:

1. First, ECDSA is one way for Alice and Bob to authenticate the ephemeral keys used in the key exchange, like you suggest in the comment. If they already know each other's ECDSA keys, they can use them to sign and verify the ephemeral keys.

2. If they require non-repudiation, they can use ECDSA to sign the messages before encryption. With only ECDH and AES-GCM there is no way to prove if Alice or Bob wrote a particular message, since either can encrypt under the same shared key. A signature would allow Alice to prove to others that Bob said something. (Whether you want non-repudiation or want to avoid it depends on the use case.)

• If you only need to guarantee privacy and authenticity - should that be "privacy and integrity" as opposed to "authenticity"? – chrixm Nov 4 '15 at 16:24
• @chrixm, AES-GCM guarantees both. Bob knows the message is from Alice if he didn't write it himself. – otus Nov 4 '15 at 17:06
• "Sometimes non-repudiation is required, but sometimes it is a failing." I'm not sure I understand that very last part of this otherwise fine answer. – Maarten Bodewes Nov 4 '15 at 17:21
• @otus on its own how does AES-GCM guarantee that the message is from Alice? Is this based on the assumption that Bob has already pre-verified that he definitely has Alice's public key via an offline method - either through comparing an SHA-256 hash or another method? If that is the case then AES-GCM provides authenticity as only Alice and Bob are able to generate the same shared secret. – chrixm Nov 4 '15 at 17:35
• @MaartenBodewes, in some situations you want public verifiability that someone really said something. In others you a protocol that has deniable authentication. ECDH + AES-GCM gives you the latter, while adding a signature gives you the former. I'll try to rephrase. – otus Nov 4 '15 at 21:03