2

There is a popular JWT library on nuget. I am analyzing an application that uses that library and it stores a secret key as a string. In the code of the library I see that it uses the MS HMACSHA256 that accepts byte array as a key. So the library does Encoding.UTF8.GetBytes(key) to pass the secret key to the library.

Since UTF8 encoding means some structure usually (e.g. some byte sequences won't match to any of the printable characters), compared to some Base64 that can have any random byte sequence, won't it mean that this key is more predictable that it should be?

Can it still be secure enough provided the proper generation of this key, and how should it be generated in this case?

Ilya Chernomordik
  • 2,197
  • 1
  • 21
  • 36

1 Answers1

1

I'm assuming here that key is something static at system level, and not something an individual user chooses - if so, it is very strange that it is read as UTF-8 rather than as Base64 because UTF-8 will be an inefficient storage mechanism for the key as it won't be using the full keyspace. I would put this down to developer naivety rather than anything done out of reason.

This method would make more sense if it was for a user chosen key, as they may have entered unicode characters as they key, and therefore if it is stored and read as UTF-8 it can then be put into a key-stretching function such as PBKDF2. Here the goal isn't efficient storage, it would be simply making sure that a user chosen key has enough entropy to be useful.

won't it mean that this key is more predictable that it should be?

When the key goes into the HMAC function, it is hashed along with the message. The fact that it is from a UTF-8 string should not make the resultant HMACs more predictable nor should it make brute-forcing the key any easier. As long as the original string has enough entropy in it to begin with, it won't matter what format it has been converted to for storage.

Can it still be secure enough provided the proper generation of this key, and how should it be generated in this case?

From this answer, a 128 bit random value generated via a cryptographically secure pseudo random number generator would be recommended for the key. The CSPRNG would generate a byte sequence, so this could be Base64'd and then stored as UTF-8, albeit with the keyspace never being completely filled. It would be better if the UTF-8 step could be completely removed though because it adds unnecessary complexity.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • Thanks for the explanation, my understanding that developers that implemented that are not very keen on security, so they did the easiest thing they ever could and put it in web.config and then read it as UTF8. It is definitely not base64, it's raw utf-8 bytes that are used as hmac secret. So I guess you really suggest to switch to base64 even though utf8 might be good enough? – Ilya Chernomordik Feb 09 '16 at 08:57
  • As long as there's enough entropy in the original key generation technique, this will be fine. – SilverlightFox Feb 09 '16 at 09:03
  • This is exactly what I am not sure about, I know how to take CSPRNG and generate bytes and convert them to base64, but I don't know how to ensure there is enough entropy in the utf8. So I guess I'll suggest to use base 64 instead – Ilya Chernomordik Feb 09 '16 at 09:06
  • If the original string has enough entropy, so does the UTF-8 derived from it. – SilverlightFox Feb 09 '16 at 09:24