# Encoding and hashing helpers

Encoding, hashing, and secret hashing functions transform content in Handlebars expressions.

The helpers described in this document can hash and otherwise transform strings using standard hashing functions, such as MD5 and SHA256. In many of these cases, you will need to transform the output to various encodings, such as Base64 or Hex.

All functions required to perform these transforms are described in this document. In all cases where strings can be provided, they are converted to UTF-8 bytes.

## Encoding

The following helpers can be used to change the encoding of a variable. They are commonly used when transforming a byte array, e.g., as output from a hash function, into readable characters.

### Base64 encode {#base64-encode}

`$base64Encode` — Given a particular string or byte array, encode to Base64.

**Properties**
* `content` — The string or byte array to encode.
* `pad` — Optional. A boolean specifying if the output should be padded. Default is `true` when unspecified.

|  Format   |  Example  |  Output  |
|---|---|---|
| `{{$base64Encode content pad=true}}` | `{{$base64Encode "wut"}}` | `d3V0` |

### Base64 decode {#base64-decode}

`$base64Decode` — Given a Base64-encoded string, decode to an array of bytes.

**Properties**
* `content` — The Base64 encoded string to decode.

|  Format   |  Example  |  Output  |
|---|---|---|
| `{{$base64Decode content}}` | `{{$utf8Decode ($base64Decode "d3V0")}}` | `wut` |

### UTF-8 decode {#utf-8-decode}

`$utf8Decode` — Given an array of bytes, decode as UTF-8 text.

**Properties**
* `content` — The bytes to decode.

For an example, see [Base64 decode](#base64-decode) above.

### UTF-8 encode {#utf-8-encode}

`$utf8Encode` — Given a string, encode as a UTF-8 byte array.

**Properties**
* `content` — The string to encode.

This function is provided as an inverse of [UTF-8 decode](#utf-8-decode).

### Hex encode {#hex-encode}

`$hexEncode` — Given a string or bytes, encode to a hex representation string.

**Properties**

* `content` — The string or bytes to encode.

|  Format   |  Example  |  Output  |
|---|---|---|
| `{{$hexEncode content}}` | `{{$hexEncode "wut"}}` | `777574` |

## Hashing

Hashing helpers are provided for the following algorithms:

* MD5: `$md5`
* SHA1: `$sha1`
* SHA256: `$sha256`
* SHA512: `$sha512`

All have the same usage but use their specified algorithm to perform the hash. These functions return byte arrays, which should then be [Hex](#hex-encode) or [Base64](#base64-encode) encoded.

**Properties**
* `content` — The string or byte array to hash.

|  Format   |  Example  |  Output  |
|---|---|---|
| `{{$<algorithm> content}}` | `{{$hexEncode ($md5 "wut")}}` | `c268120ce3918b1264fe2c05143b5c4b` |

## HMAC

[HMAC](https://en.wikipedia.org/wiki/HMAC) hash functions are provided for the following common algorithms:

* MD5: `$hmacMd5`
* SHA1: `$hmacSha1`
* SHA256: `$hmacSha256`
* SHA512: `$hmacSha512`

All have the same usage but use their specified algorithm to perform the hash. These functions return byte arrays, which should then be [Hex](#hex-encode) or [Base64](#base64-encode) encoded.

**Properties**
* `content` — The string or byte array to hash.
* `secret` — The secret key used to sign the hash.

|  Format   |  Example  |  Output  |
|---|---|---|
| `{{$hmac<algorithm> content secret=secret}}` | `{{$hexEncode ($hmacSha1 "value" secret="key")}}` | `57443a4c052350a44638835d64fd66822f813319` |

## Encryption

Symmetrical AES Encryption is provided by the `$aes` helper using AES in CBC mode with PKC55 padding. Output is Base64 encoded automatically.

**Properties**
* `content` - The string or byte array to encrypt
* `secret` - A 256-bit (32 character) string used to encrypt the content.
* `iv` - A 128-bit (16 character) initialization vector. To avoid compromising security, the initialization vector should be unique for each encryption.

|  Format   |  Example  |  Output  |
|---|---|---|
| `{{$aes content secret=secret iv=iv}}` | `{{$aes 'This string is encrypted' secret='7C45C93E-5216-48ED-88D4-6EB7C413' iv='myinitialization' }}` | `bwNBr+/yfYYPoE2aq/zqfzp6kxctfFC+MCgacwwkJSQ=` |

Below is a reference implementation for decryption of the above example using NodeJS.

```javascript
const crypto = require('node:crypto');

const decipherIV = crypto.createDecipheriv(
    'AES-256-CBC', 
    Buffer.from('7C45C93E-5216-48ED-88D4-6EB7C413'), 
    Buffer.from('myinitialization')
);
let decrypted = decipherIV.update(
    'bwNBr+/yfYYPoE2aq/zqfzp6kxctfFC+MCgacwwkJSQ=', 
    'base64', 
    'utf8'
);
decrypted += decipherIV.final('utf8');

console.log(decrypted);
// Will output "This string is encrypted"
```
