Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the preferred way of comparing hmac signatures in Node?

I've read that doing a string comparison is not the preferred way to determine if hmac signatures match. (Go to Step 5) So, in Node, given something like this

const hmac = crypto.createHmac("sha256", signingSecret).update(buf, encoding);
const computed = `${version}=${hmac.digest('hex')}`;

if(computed !== req.header("signature")){
   throw
}

If not for string comparison, what is the preferred way of doing this line: computed !== req.header("signature")?

like image 626
Newtang Avatar asked Jul 23 '18 20:07

Newtang


People also ask

How do I validate my HMAC signature?

After receiving the message, your app should verify the HMAC signature by attempting to re-create one or both of the signatures by hashing the raw message body with one or both of the app's HMAC keys. To verify the signatures: Extract the text of the UTF-8 payload as an array of bytes.

What is cryptography in node JS?

Crypto is a module in Node. js which deals with an algorithm that performs data encryption and decryption. This is used for security purpose like user authentication where storing the password in Database in the encrypted form. Crypto module provides set of classes like hash, HMAC, cipher, decipher, sign, and verify.

What is hash in node JS?

The hash. digest( ) method is an inbuilt function of the crypto module's Hash class. This is used to create the digest of the data which is passed when creating the hash. For example, when we create a hash we first create an instance of Hash using crypto.


1 Answers

The reason why an ordinary string comparison is not preferred is that it will typically return a result as soon as it finds a difference between the two strings. This can open the door to a timing-based attack; if I'm trying to guess the correct HMAC for a message and my guess differs from the real string in its first character, I'll get a "fail" response more quickly than if the difference is in the second, third, fourth ... character. Yes, the time difference is tiny, but it really can be measurable.

The preferred technique is to use what's called a "constant-time comparison" function. This kind of function is designed to consume the same amount of time regardless of the position where the arguments differ. By not returning as soon as it finds a mismatch, it gives an attacker no information about the position of the mismatch.

In Node the appropriate function is crypto.timingSafeEqual(a,b).

like image 198
ottomeister Avatar answered Sep 22 '22 13:09

ottomeister