11

I'm looking to implement HMACSHA256 request signing in an API I'm building. From what I understood from https://www.rfc-editor.org/rfc/rfc4868, it's best that the secret key be the same number of bits as the hashing algorithm (i.e. SHA256 secret keys should be 256 bits/32 bytes).

Can I use one of the many different random number generators out there for C# or is there a specific way that these keys need to be generated.

Lastly, Amazon Web Services uses HMACSHA256, but they secret keys they provide (at least to me) is 320 bits/40 bytes (when the key is converted to bytes using UTF-8, see https://github.com/aws/aws-sdk-net/blob/master/AWSSDK/Amazon.Runtime/Internal/Auth/AWS4Signer.cs#L205-L232). Is there a reason to use more than needed by the hashing algorithm since it's truncated?

Community
  • 1
  • 1
Omar
  • 39,496
  • 45
  • 145
  • 213

2 Answers2

29

One way to generate a (presumably secure) key is:

var hmac = new HMACSHA256();
var key = Convert.ToBase64String(hmac.Key);
Omar
  • 39,496
  • 45
  • 145
  • 213
10

If a key is longer than the HMAC supports, it'll usually be hashed to the proper size. This is mainly to support human-readable keys of arbitrary length. If you're generating a key programatically and don't need it to be human-readable, I'd recommend using RandomNumberGenerator. This is basically what it was made for.

using System.Security.Cryptography;

using RandomNumberGenerator rng = RandomNumberGenerator.Create();

byte[] data = new byte[32];
rng.GetBytes(data);
Krzaku
  • 186
  • 4
  • 16
Cory Nelson
  • 29,236
  • 5
  • 72
  • 110