jwt icon indicating copy to clipboard operation
jwt copied to clipboard

HMAC: add Blake2b signature algorithm

Open Slamdunk opened this issue 3 years ago • 16 comments

Hi, JWT has never formalized Blake2b as a signing algorithm, hence the BLAKE2B algorithm ID I chose in the code was made up by me and I don't know if this should be merged of not, maybe we could use the @experimental tag on the class, I don't know.

But if this is nowhere near a standard (in JWT I mean, Blake2b is a standard), why proposing it? Because of this:

+--------------+-------------------+-----+------+-----+----------+-----------+---------+
| benchmark    | subject           | set | revs | its | mem_peak | mode      | rstdev  |
+--------------+-------------------+-----+------+-----+----------+-----------+---------+
| EddsaBench   | benchSignature    |     | 100  | 5   | 4.359mb  | 20.221μs  | ±2.59%  |
| EddsaBench   | benchVerification |     | 100  | 5   | 4.359mb  | 45.970μs  | ±0.62%  |
| Sha256Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 60.589μs  | ±6.34%  |
| Sha256Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 95.866μs  | ±4.34%  |
| Sha384Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 61.166μs  | ±1.13%  |
| Sha384Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 104.584μs | ±0.76%  |
| Sha512Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 60.701μs  | ±5.33%  |
| Sha512Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 114.601μs | ±1.13%  |
| Sha256Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 837.150μs | ±3.02%  |
| Sha256Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 36.188μs  | ±3.82%  |
| Sha384Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 803.909μs | ±3.31%  |
| Sha384Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 38.787μs  | ±3.91%  |
| Sha512Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 791.626μs | ±1.59%  |
| Sha512Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 36.873μs  | ±3.04%  |
| NoneBench    | benchSignature    |     | 100  | 5   | 4.359mb  | 0.123μs   | ±38.90% |
| NoneBench    | benchVerification |     | 100  | 5   | 4.359mb  | 0.170μs   | ±2.33%  |
| Sha256Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 2.218μs   | ±8.02%  |
| Sha256Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 2.410μs   | ±0.20%  |
| Sha384Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 2.262μs   | ±13.38% |
| Sha384Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 2.451μs   | ±0.33%  |
| Sha512Bench  | benchSignature    |     | 100  | 5   | 4.359mb  | 2.285μs   | ±6.95%  |
| Sha512Bench  | benchVerification |     | 100  | 5   | 4.359mb  | 2.491μs   | ±10.81% |
| Blake2bBench | benchSignature    |     | 100  | 5   | 4.359mb  | 0.562μs   | ±2.72%  |
| Blake2bBench | benchVerification |     | 100  | 5   | 4.359mb  | 0.760μs   | ±0.83%  |
+--------------+-------------------+-----+------+-----+----------+-----------+---------+

Slamdunk avatar Apr 05 '22 13:04 Slamdunk

Threw it out to pull in some attention: https://twitter.com/Ocramius/status/1511338900043841537

Ocramius avatar Apr 05 '22 13:04 Ocramius

I'm okay too (100% agree with the documentation comments).

lcobucci avatar Apr 05 '22 17:04 lcobucci

Looks okay to me, would you please add the docs?

lcobucci avatar Apr 06 '22 17:04 lcobucci

Sure, tomorrow

Slamdunk avatar Apr 06 '22 17:04 Slamdunk

Woah, this is great.

jedisct1 avatar Apr 06 '22 23:04 jedisct1

One consideration to check here: is the generated hash longer or shorter, and how much? A longer hash would mean lower CPU load, but higher I/O load.

I see Blake2B is supposed to produce 64 bytes? If that is the case, it is most likely a big win also for everything I/O related.

EDIT: as for security guarantees, it seems like Blake2b is theorically a lot better than sha256

Ocramius avatar Apr 06 '22 23:04 Ocramius

I see Blake2B is supposed to produce 64 bytes?

It can range between 16 and 64, but default implementation including libsodium's one is 32 bytes, so same output length as sha256. the most common JWT sym-algo

Slamdunk avatar Apr 07 '22 05:04 Slamdunk

For long-term tokens, a minimum of 24 bytes is required for collision resistance. 16 bytes are fine for short-lived tokens. 32 bytes are safe for all use cases, adds a security margin.

Using 64 bytes would be useless in the case of JWT.

Speed is the same regardless of the output size; what really matters is the block size (how many bytes are processed at one) and it is always 512 bits in BLAKE2b.

So, like @Slamdunk I'd also recommend using 32 bytes output.

jedisct1 avatar Apr 07 '22 08:04 jedisct1

BLAKE2b also accepts an optional "personalization" parameter (sometimes called "context" in other hash functions and constructions). The purpose is to produce a different output in case the same key is used in different contexts, in order to avoid cross-protocol attacks.

Setting it to a constant such as the "JWT" string may not be a bad idea.

jedisct1 avatar Apr 07 '22 08:04 jedisct1

BLAKE2b also accepts an optional "personalization" parameter

libsodium doesn't expose it on high-level API (see https://libsodium.gitbook.io/doc/hashing/generic_hashing#notes).

I like the idea but I want to stick to a standard implementation as much as possible.

Slamdunk avatar Apr 07 '22 08:04 Slamdunk

I know, I'm libsodium's author :)

It's available as crypto_generichash_blake2b_salt_personal().

The parameter is available in all other BLAKE2b implementations as well.

jedisct1 avatar Apr 07 '22 08:04 jedisct1

Some interesting discussions in https://mailarchive.ietf.org/arch/msg/jose/YAQf8peqpqNTNpK2VJFFckbR1P4/. @jedisct1 maybe you can help out?

lcobucci avatar Apr 11 '22 11:04 lcobucci

From that mail thread:

As for process for adding it, I would write Internet-Draft specifying the use in JOSE and then use the I-D as specification for expert review. One might do a comment round through this list first to catch the worst issues...

Sounds like it may take a while, if it ever happens at all.

Ocramius avatar May 16 '22 15:05 Ocramius

From that mail thread:

As for process for adding it, I would write Internet-Draft specifying the use in JOSE and then use the I-D as specification for expert review. One might do a comment round through this list first to catch the worst issues...

Sounds like it may take a while, if it ever happens at all.

Like all standards. It take years for a proposal to become accepted as a standard, if that ever happens, and by the time it finally happens, the algorithm is already obsolete.

jedisct1 avatar May 16 '22 16:05 jedisct1

Like all standards. It take years for a proposal to become accepted as a standard, if that ever happens, and by the time it finally happens, the algorithm is already obsolete.

Yeap... looking at timelines as https://datatracker.ietf.org/doc/rfc8037/ makes me shiver... I don't have the capacity to create the draft (I'm even struggling to keep up with basic OSS).

We must decide if we want to push this further (just remove references from HMAC as native Blake2b MAC is different from HMAC-Blake2) and accept the usage of a non-standard algorithm or hold this until someone creates the Internet Draft and submit it for review (following RFC7518's procedure).

Even if not the case here, sigantures using BLAKE2B as hash would be significantly more problematic: The only space/time efficient signature algorithm allowing variable hashes that is even close to widespread is ECDSA, and ECDSA requires bit order of hash, which BLAKE2 just does not specify.

That bit also came from the thread and makes me feel like the "Designated Experts" might reject BLAKE2b's submission, idk. I'm honestly not knowledgeable enough on the nitty-gritty details of hashing to understand if not requiring bit order of hash would be a potential problem for Blake2b's adoption - I don't really mind the fact it's not widespread atm.

I'm generally okay with adding a non-standard algorithm if you're all up to it.

lcobucci avatar May 16 '22 19:05 lcobucci

"de facto" standards work.

If common implementations are compatible with each other, this is enough to make something a lot of people can use and take advantage of.

jedisct1 avatar May 17 '22 17:05 jedisct1