I am writing an application using JSON Web Encryption with ECDH using the X25519 Curve. The RFC says that ECHD-ES derived secret is run through a Concat KDF.

Given that many cryptographers seem to be bashing JWT and the JOSE standard for having too many options to shoot yourself in the foot I want to make sure I am not using an insecure mode of JWE.

RFC 7518 JSON Web Algorithms (JWA) states

Key Agreement with Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES)

This section defines the specifics of key agreement with Elliptic
Curve Diffie-Hellman Ephemeral Static [RFC6090], in combination with
the Concat KDF, as defined in Section 5.8.1 of [NIST.800-56A].

Following the reference leads to 152 page NIST PDF that I don't fully understand. I am a developer not a cryptographer. I am using the Nimbus JOSE library in my application and it has an implementation of ContcatKDF.java derive function there.


  • How does Contcat KDF work?
  • Is it considered secure?

It derive function gets called with SHA-256 as the hash function concatKDF = new ConcatKDF("SHA-256"); from ECDHCryptoProvider.java which computes the number of cycles using this.

Moderator note: crypto-SE is not a code review site. The code was replaced by links to the code. It's still here if needed.

  • 1
    $\begingroup$ Oh, dear. That implementation is correct w.r.t. the scheme compared to SP800-56Ar1. However, the deriveKey in there scares the hell of me. I mean, how many copies of key material do you want to use? The output keying material is even written to a ByteArrayOutputStream which is not initialized with the correct number of bytes either. And who calls md.update(sharedSecret.getEncoded()); in a loop? Sigh. $\endgroup$
    – Maarten Bodewes
    Oct 21, 2020 at 12:37
  • $\begingroup$ @Maarten Bodewes: Agreed. I'll abstain from commenting the code (which I purposedly moved out of the question). I know no way to security-audit Java code anyway, because JVM and JiTC and so many things I don't even know they exist. $\endgroup$
    – fgrieu
    Oct 21, 2020 at 12:39
  • $\begingroup$ I rewrote it for a bit too keep practicing. ams, if you're interested I can share it, but it won't fit into the fantastic JOSE framework anymore. Oh, and it isn't thread safe anymore either. I'll be buggered if I know why you'd want a thread safe crypto class though if you can perfectly share the frickin' key. $\endgroup$
    – Maarten Bodewes
    Oct 21, 2020 at 17:05
  • $\begingroup$ @MaartenBodewes, I would be interested to look at the alternative implementation maybe an issue with suggested code changes on the Nimbus Library issue tracker could be good. $\endgroup$
    – ams
    Oct 22, 2020 at 19:02

1 Answer 1


Looking at it closely, the linked RFC formally references SP800-56Ar2 section 5.8.1, which buries in

Note: When the single-step KDF specified in Section is used with H = hash as the auxiliary function and this concatenation format for OtherInfo, the resulting key-derivation method is the Concatenation Key Derivation Function specified in the original version of SP 800-56A. (emphasis mine)

Based also on this, I guess that when the authors of the RFC wrote "Concat KDF, as defined in Section 5.8.1 of [NIST.800-56A]", they had in mind SP800-56Ar1 section 5.8.1, titled "Concatenation Key Derivation Function (Approved Alternative 1)", which is what I would use if I had to implement the thing. I suggest to ignore the RFC's reference to the aforementioned SP800-56Ar2, which seems to be a well-intentioned but unfortunate change; as well as the currently applicable SP800-56Ar3.

Big picture: that KDF hashes the concatenation of a 4-byte counter initialized at 1 (big-endian), the shared secret obtained by ECDH, and some other information passed as input. The counter is incremented and the process is repeated until enough data was produced. The concatenation of the hashes, truncated as needed, forms the output to be used as key. Except for the data hashed and the position of the counter (at start rather than end), this is similar in principle to MGF1 of RSASSA-PSS and RASAES-OAEP in PKCS#1v2.2.

If the hash is SHA-256 as now in the question, as well as in this code which claims to successfully implement something (without stating clearly against what it is tested), I do not see that this KDF has an exploitable weakness of cryptographic nature in the context. This is not a statement about code.

  • 1
    $\begingroup$ The KDF's in NISTs documentation are used to specify which algorithms are deemed secure. They often fail to standardize anything in that sense, and a clear reasoning why they are as they are is often omitted. This makes it near impossible to standardize on them. Even with the modern KDF's a lot of possible KDF's are specified, which is why you get different HSM's standardizing on different KDF's - not very useful. The Concatenation KDF is almost identical to KDF1/2, but for the location of the counter - sigh. $\endgroup$
    – Maarten Bodewes
    Oct 20, 2020 at 7:39
  • 1
    $\begingroup$ I have updated the question with link to the Nimubs implementation of ContactKDF it is called form the ECDH provider with concatKDF = new ConcatKDF("SHA-256"); $\endgroup$
    – ams
    Oct 20, 2020 at 16:25
  • 1
    $\begingroup$ Is there a reason that concat KDF was used and not HKDF? $\endgroup$ Sep 17, 2022 at 7:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.