2

I am trying to implement ECIES properly with X25519/HKDFwithSHA256/AES-128-GCM with Node.js crypto library. It is not clear to me how to determine the input key material (IKM) to HKDF.

Initially, I thought it is okay to directly use the shared secret generated by X25519 as the IKM.

const {diffieHellman, hkdfSync} = require('crypto');
const sharedKey = diffieHellman({
  privateKey,
  publicKey,
});
const aesKey = hkdfSync('sha256', sharedKey, '', '', 16);

But apparently, if diffieHellman does not contain publicKey and the output only contains the x-coordinate of a point, then this is not CCA2-secure, as mentioned in https://eprint.iacr.org/2001/112.pdf:

There are a number of simple examples that illustrate why ECIES does not achieve this level of security. In particular, it is malleable. If the group is an elliptic curve, and the partial encoding function E′ encodes only the x-coordinate of a point, then the derived key K is the same if one takes a given ciphertext $C_0$ encoding a point $\tilde{g}$ and replaces it with an encoding of $−\tilde{g}$.

Some implementations of X25519 also suggests users to include the public values as inputs to the KDF.

Do not use the shared key directly, rather use a key derivation function and also include the two public values as inputs.

Is it sufficient to use the shared secret directly as IKM? If not, what is the proper way to include the public key in the IKM?

Eri
  • 31
  • 3
  • 2
    It might be worth it to use HPKE https://blog.cloudflare.com/hybrid-public-key-encryption/) instead of writing your own ECIES protocol. If you want to anyway, you can see how they use HKDF with LabeledExpand and LabeledExtract functions. – rozbb Aug 01 '23 at 16:41
  • 1
    The shared secret is meant to be used as the IKM, but the public keys concatenated together should be used in the info parameter. Including the public keys in the key derivation is mentioned in RFC 7748. – samuel-lucas6 Aug 01 '23 at 19:36
  • @rozbb Good to know about HPKE. However, it seems like to me there is no popular Node.js/TypeScript/JavaScript implementation yet... – Eri Aug 02 '23 at 09:04
  • It looks like hpke-js, referenced in the RFC draft repo https://github.com/cfrg/draft-irtf-cfrg-hpke, is pretty featureful – rozbb Aug 03 '23 at 00:05

1 Answers1

-4

To use HKDF (HMAC-based Key Der255:

. Generate an ephemeral X25519 private key. 2. Use the private key to compute. Perform a key exchange with the other party's public key using X25519. 4. Use the resulting shared secret as the input keying material (IKM) for HKDF. 5 Set an appropriate salt value, if required, for HKDF. 6. Use HKDF with the the input key material, the salt value, and the desired output length.

Here is an example code in Python using the cryptography library:

from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
 cryptography.hazmatimitives import hkdf

Generate ephemeral X25519 private key

private_key = X25519PrivateKey.generate()

Compute corresponding public key

public_key = private_key.public_key()

Perform key exchange with other party's public

shared_secret = private_key.exchange_key)

derived_keydf.HKDF( algorithm=hkdf.HMACAlgorithm.SHA256, length=32, # Length of desired output key salt=salt, info=b"", ).derive(shared_secret# Use derived key for cryptographic operations

(e.g., encryption, authentication, etc.)

Remember to handle errors, securely store private keys, and properly manage the lifecycle of cryptographic materials.