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:
Name | Type | Default | Description |
---|---|---|---|
algorithm Required | string | Digest algorithm to use (sha1, sha256, sha3-256,... ) | |
key Required | string | Buffer | Secret key to use on the hmac | |
data Required | string | Buffer | String or buffer to hmac | |
options | GenericOptions | {} | Optional configuration object for input data encoding and output |
Options:
Name | Type | Default | Description |
---|---|---|---|
inputDataEncoding | BufferEncoding | Specifies the encoding of the input data (e.g., 'hex', 'base64'). | |
inputKeyEncoding | BufferEncoding | Specifies 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:
Name | Type | Default | Description |
---|---|---|---|
algorithm Required | string | Digest algorithm to use (sha1, sha256, sha3-256,... ) | |
key Required | string | Buffer | Secret key to use on the hmac | |
data Required | string | Buffer | String or buffer to hmac | |
oldHmac Required | string | Buffer | String or buffer of the existing hmac | |
options | GenericOptions | {} | Optional configuration object for input data encoding and output |
Options:
Name | Type | Default | Description |
---|---|---|---|
inputDataEncoding | BufferEncoding | Specifies the encoding of the input data (e.g., 'hex', 'base64'). | |
inputKeyEncoding | BufferEncoding | Specifies 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:
Name | Type | Default | Description |
---|---|---|---|
data Required | string | Buffer | String or buffer to hmac | |
options | GenericOptions | {} | Optional configuration object for input data encoding and output |
Options:
Name | Type | Default | Description |
---|---|---|---|
inputDataEncoding | BufferEncoding | Specifies 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.
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:
Name | Type | Default | Description |
---|---|---|---|
data Required | string | Buffer | String or buffer to hmac | |
oldHmac Required | string | Buffer | String or buffer of the existing hmac | |
options | GenericOptions | {} | Optional configuration object for input data encoding and output |
Options:
Name | Type | Default | Description |
---|---|---|---|
inputDataEncoding | BufferEncoding | Specifies 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...
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=