Skip to main content
Version: 3.x

HMAC

In this section, we will dive into various methods for applying cryptographic HMAC hash-based message authentication code both generically and securely. We will cover best practices to ensure that the hmac process is robust against common vulnerabilities. Additionally, we will explore secure techniques for comparing hmac values, focusing on the use of time-safe comparison functions to prevent timing attacks. These methods are crucial for ensuring the integrity and security of sensitive data in cryptographic operations.

Create a custom HMAC

Generic

Method to create a hmac of a text where you could choose the desired digest algorithm to use sha1, sha256, sha3-256,...

createCustomHmac

public createCustomHmac (
algorithm: string,
key: string | Buffer,
data: string | Buffer,
options?: GenericOptionsInterface,
): Buffer;

Parameters:

NameTypeDefaultDescription
algorithm RequiredstringDigest algorithm to use (sha1, sha256, sha3-256,...)
key Requiredstring | BufferSecret key to use on the hmac
data Requiredstring | BufferString or buffer to hmac
optionsGenericOptions{}Optional configuration object for input data encoding and output

Options:

NameTypeDefaultDescription
inputDataEncodingBufferEncodingSpecifies the encoding of the input data (e.g., 'hex', 'base64').
inputKeyEncodingBufferEncodingSpecifies the encoding of the input key (e.g., 'hex', 'base64').

Outputs:

As output, it will return a Buffer <Buffer cc 2b.....cd a1 08>

Usage:

async exampleHmac(
data: string,
): string {
const hmacResult = this.cryptographyService.createCustomHmac(
'sha512',
'strong_key',
'test',
{
inputDataEncoding: 'utf-8',
inputKeyEncoding: 'utf-8',
}
);
return hmacResult.toString('hex')
}

Verify a custom HMAC

Generic

Method to verify if an existing hmac matches the hmac of the desired text. You need choose the existing hmac algorithm type used sha1, sha256, sha3-256,...

verifyCustomHmac

public verifyCustomHmac (
algorithm: string,
key: string | Buffer,
data: string | Buffer,
oldHmac: string | Buffer,
options?: GenericOptionsInterface,
): boolean;

Parameters:

NameTypeDefaultDescription
algorithm RequiredstringDigest algorithm to use (sha1, sha256, sha3-256,...)
key Requiredstring | BufferSecret key to use on the hmac
data Requiredstring | BufferString or buffer to hmac
oldHmac Requiredstring | BufferString or buffer of the existing hmac
optionsGenericOptions{}Optional configuration object for input data encoding and output

Options:

NameTypeDefaultDescription
inputDataEncodingBufferEncodingSpecifies the encoding of the input data (e.g., 'hex', 'base64').
inputKeyEncodingBufferEncodingSpecifies the encoding of the input key (e.g., 'hex', 'base64').

Outputs:

As output, it will return true if both matches, or false if not.

This method uses a time-safe comparison function to prevent timing attacks

Usage:

async checkHmac(
oldKey: string,
existingHmac: string,
data: string,
): boolean {
const bufferExistingHmac = Buffer.from(existingHmac, 'hex');
return this.cryptographyService.verifyCustomHmac(
'sha512',
oldKey,
data,
bufferExistingHmac,
{
inputDataEncoding: 'utf-8',
inputKeyEncoding: 'hex',
},
);
}

Create a secure HMAC

Recommended

Method to create an extra secure hmac of a text.

In this case the sha3-256 digest algorithm will be used.

createSecureHmac

public createSecureHmac (
data: string | Buffer,
options?: GenericOptionsInterface,
): Buffer;

Parameters:

NameTypeDefaultDescription
data Requiredstring | BufferString or buffer to hmac
optionsGenericOptions{}Optional configuration object for input data encoding and output

Options:

NameTypeDefaultDescription
inputDataEncodingBufferEncodingSpecifies the encoding of the input data (e.g., 'hex', 'base64').

Outputs:

As output, it will return a Buffer <Buffer cc 2b.....cd a1 08>

Usage:

async exampleSecureHmac(
data: string,
): string {
const hmacResult = this.cryptographyService.createSecureHmac(
data,
{
inputDataEncoding: 'utf-8',
},
);
return hmacResult.toString('hex')
}

Verify a secure HMAC

Recommended

Method to verify if an existing hmac matches the hmac of the desired text.

warning

Remember that the previous hmac must have been generated using createSecureHmac method.

verifySecureHmac

public verifySecureHmac (
data: string | Buffer,
oldHmac: string | Buffer,
options?: GenericOptionsInterface,
): boolean;

Parameters:

NameTypeDefaultDescription
data Requiredstring | BufferString or buffer to hmac
oldHmac Requiredstring | BufferString or buffer of the existing hmac
optionsGenericOptions{}Optional configuration object for input data encoding and output

Options:

NameTypeDefaultDescription
inputDataEncodingBufferEncodingSpecifies the encoding of the input data (e.g., 'hex', 'base64').

Outputs:

As output, it will return true if both matches, or false if not.

This method uses a time-safe comparison function to prevent timing attacks

Usage:

async exampleVerifySecureHmac(
data: string,
existingHmac: string,
): boolean {
const bufferExistingHmac = Buffer.from(existingHmac, 'hex');
return this.cryptographyService.verifySecureHmac(
data,
bufferExistingHmac,
{
inputDataEncoding: 'utf-8',
},
);
}

🛟 Tips

Remember that...
info

Remember that buffers could be transformed to utf8, hex, base64, latin,... using the toString() method.

let passwordAsBuffer: Buffer = someMethodThatReturnsABuffer();

console.log(passwordAsBuffer.toString('hex')) // f32.....4ee
console.log(passwordAsBuffer.toString('base64')) // 8OI.....ZQ=