4

I'm a building a RESTful stateless API and I'm using a token for authentication. The problem I'm having is I'm not sure how secure HMAC is.

I'm using a JSON Web Token library that let's me encrypt and decrypt the data I pass in.

Basically, the way it works is this:

If I pass it this JSON:

{
    token: "asdasdasdass",
    userId: 1234    
}

It returns 325345ljljn5llnk4.245j4k5j4525ñ4j55n, where the first part is the JSON base64 encoded and the second part is the HMAC.

For example if I put:

{
    sessionId: 145
}

Is there any way an attacker could generate a valid token with the session ID he wants? Is it doable?

Also, how long should my key length be?

I didn't find answers on this site... and I've been reading a lot.

  • have you read the OWASP guides on this issue? https://www.owasp.org/index.php/REST_Security_Cheat_Sheet – schroeder Oct 14 '14 at 19:33
  • 1
    JWT relies on a key to sign or encrypt the token, so an attacker could create the JSON but without the correct key the attack should fail. You need to ensure that your API only accepts valid tokens. And preferably use a more secure hash algorithm like SHA256. – Bernie White Oct 15 '14 at 08:06

1 Answers1

3

HMAC is a keyed message authentication code construction. As Bernie mentioned in the comments, an attacker who does not have your secret key (assuming the implementation is strong, of course), cannot create a valid HMAC for modified data.

The answer to your second question: "How long should my key length be?" depends on the specific hash function that you're using within HMAC. Ideally, the key length should equal the output length, so for HMACSHA1, you would use a 160-bit key, for HMACSHA256, a 256-bit key, for HMACSHA512, a 512-bit key, and so forth.

Xander
  • 35,525
  • 27
  • 113
  • 141
  • Wow, thank you, this is the answer I was expecting. I'm using SHA256, so I should enter a 256-bit key. Now, it means a 32 characters length string or is it programming language dependent or how it works. I know the library I'm using internally uses [this function](http://nodejs.org/api/crypto.html#crypto_crypto_createhmac_algorithm_key). – Gaston Sanchez Oct 16 '14 at 05:33
  • @user1781670 Internally the value is binary. Bytes, rather than characters. The number of bytes per character *could* indeed vary from platform to platform and data type to data type, as you'll get differences between ASCII and various flavors of Unicode, for instance. I would generally advise to use a cryptographically strong pseudo-random number generated to create the correct number of random bytes (32 for 256 bits) and then encode them using base64 or hex, and treat the key as binary data rather than a string. In, I believe you can do this by creating a Buffer() and defining the encoding. – Xander Oct 16 '14 at 13:04