Skip to main content
Version: 3.x

Symmetric Encryption

In this section, we will discuss symmetric encryption and decryption using AES-256-GCM,focusing on best practices to ensure robust security. AES-256-GCM is a widely used and highly secure cryptographic algorithm, but its strength depends heavily on proper implementation. Key best practices include never reusing initialization vectors (IVs), as doing so can compromise the encryption's integrity. It is also crucial to always derive a secure encryption key from the user-provided key using a strong key derivation function like Argon2 or HKDF. In certain cases, it’s recommended to encapsulate the Data Encryption Key (DEK) by encrypting it separately, providing an additional layer of security for sensitive operations. Following these principles ensures that your symmetric encryption implementations remain secure and resilient against common cryptographic attacks.

Symmetric secure data encrypt

Recommended

Method to encrypt data using AES-256-GCM with a randomly generated Data Encryption Key (DEK). It ensures security by generating unique IVs and salts using the createSafeRandomData, securely deriving encryption keys, and encrypting the DEK using a master key. The final output is a concatenation of the encrypted DEK and the encrypted data, ensuring both confidentiality and key encapsulation.

symmetricSecureDataEncrypt

public symmetricSecureDataEncrypt (
data: string | Buffer,
options?: GenericOptionsInterface,
): Promise<Buffer>;

Parameters:

NameTypeDefaultDescription
data Requiredstring | BufferString or buffer to encrypt
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>

info

The resulting buffer contains: [CIPHERED_DEK + CIPHERED_DATA]

  • And CIPHERED_DEK buffer part contains: [IV + SALT + AUTH_TAG + CIPHERED_DATA]
  • And CIPHERED_DATA buffer part contains: [IV + SALT + AUTH_TAG + CIPHERED_DATA]

Click here to see more in deep how it works

Usage:

async exampleEncrypt(
data: string,
): Promise<string> {
const encryptedData = await this.cryptographyService.symmetricSecureDataEncrypt(
data,
{
inputDataEncoding: 'utf-8',
},
);
return encryptedData.toString('hex')
}

Symmetric secure data decrypt

Recommended

Method to decrypt data that was encrypted using the method symmetricSecureDataEncrypt

warning

Remember that the previous data must have been encrypted using symmetricSecureDataEncrypt method.

symmetricSecureDataDecrypt

public symmetricSecureDataDecrypt (
data: string | Buffer
): Promise<Buffer>;

Parameters:

NameTypeDefaultDescription
data Requiredstring | BufferString or buffer to decrypt
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 exampleDecrypt(
data: string,
): Promise<string> {
const decryptedData = await this.cryptographyService.symmetricSecureDataDecrypt(
data,
{
inputDataEncoding: 'hex',
},
);
return decryptedData.toString('utf-8')
}

Symmetric data encrypt

Generic

Method to encrypt data using AES-256-GCM and using unique IVs and salts using the createSafeRandomData, and deriving the encryption key using Argon2 KDF.

This is the internal method used to encrypt the data and the DEK when using symmetricSecureDataEncrypt

symmetricDataEncrypt

public symmetricDataEncrypt (
data: string | Buffer,
key: string | Buffer,
options?: GenericOptionsInterface,
): Promise<Buffer>;

Parameters:

NameTypeDefaultDescription
data Requiredstring | BufferString or buffer to encrypt
key Requiredstring | BufferString or buffer of the key to use
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>

info

The resulting buffer contains: [IV + SALT + AUTH_TAG + CIPHERED_DATA]

Usage:

async exampleEncrypt(
data: string,
): Promise<string> {
const encryptedData = await this.cryptographyService.symmetricDataEncrypt(
data,
'secret_key',
{
inputDataEncoding: 'utf-8',
inputKeyEncoding: 'utf-8'
},
);
return encryptedData.toString('hex')
}

Symmetric data decrypt

Generic

Method to decrypt data that was encrypted using the method symmetricDataEncrypt

symmetricDataDecrypt

public symmetricDataDecrypt (
data: string | Buffer,
key: string | Buffer,
options?: GenericOptionsInterface,
): Promise<Buffer>;

Parameters:

NameTypeDefaultDescription
data Requiredstring | BufferString or buffer to decrypt
key Requiredstring | BufferString or buffer of the key to use
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 exampleDecrypt(
data: string,
): Promise<string> {
const decryptedData = await this.cryptographyService.symmetricDataDecrypt(
data,
'secret_key'
{
inputDataEncoding: 'hex',
inputKeyEncoding: 'utf-8',
},
);
return decryptedData.toString('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=