dotnet / dotnet-api-docs

.NET API reference documentation (.NET 5+, .NET Core, .NET Framework)
https://docs.microsoft.com/dotnet/api/
Other
699 stars 1.54k forks source link

Error in key parameter description #1954

Open colgreen opened 5 years ago

colgreen commented 5 years ago

This sentence is incorrect ... "If the key is more than 64 bytes long, it is hashed (using SHA-256) to derive a 64-byte key."

What actually happens is that if the key is longer than 64 bytes then it is SHA-256 hashed to 32 bytes (which is 256 bits), and zero padding is applied to create the 64 byte key.

Also, see this discussion that suggests that using 32bits of entropy in the HMAC key is probably OK:

Key size for HMAC-SHA256

Then again, it's possible the author(s) of HMACSHA256 intended to keep 64 bytes of entropy if more than 64 bytes are supplied, so maybe the docs are 'correct' and the implementation is wrong.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

rpetrusha commented 5 years ago

@bartonjs, could you take a look at this issue, please?

bartonjs commented 5 years ago

It is true that it is hashed to 32 bytes, it is also true that the 32-byte is effectively stretched (via appended zeros) to a 64-byte key.,

So I'd say that what's there is correct, but perhaps misleading or confusing. Maybe a reasonable alternative is

"If key is more than 64 bytes long it is first hashed (using SHA-256) down to 32 bytes. Any key value less than 64 bytes (including a large key that got hashed) is padded to produce a 64-byte internal value."

As for the recommended size... 64 bytes is the "best" value (provided it was a random or derived key). RFC 2104 recommends a minimum size of the hash output size (256-bit (32 bytes) for HMACSHA256), and I'd agree that anything 32-bytes or more is sufficient (provided it's a random or derived key). I don't know a good way to cut that down to a nice, simple, recommendation. ("The key can be any length, however the minimum recommended size is 32 bytes."? Combined with the "what happens" maybe that's enough for someone to realize there's a maximum at 64)

colgreen commented 5 years ago

Thanks. FWIW here's my slightly edited version of your first paragraph...

"If key is more than 64 bytes long it is first hashed (using SHA-256) to produce a 32 byte hash and padded with zero bytes to produce the final 64 byte key. If key is shorter than 64 bytes it is padded with zero bytes to produce the final 64 byte key."

I do feel like a variation on your second block of text needs to be in there - I was rather puzzled when I looked at the source code, and it was that crypto.stackexchange.com post that helped clarify why the logic is how it is.

(I appreciate now that the docs aren't incorrect, but could be clearer).