---
title: crypto.decrypt_hex
summary: null
url: >-
  https://www.fastly.com/documentation/reference/vcl/functions/cryptographic/crypto-decrypt-hex
---

```
STRING crypto.decrypt_hex(ID cipher, ID mode, ID padding, STRING key_hex, STRING iv_hex, STRING plaintext_base64)
```

**Available in:** all subroutines

Symmetric key decryption.

All inputs (key, IV, ciphertext) must be hex-encoded strings. The returned plaintext is also hex-encoded.

## Parameters

| Parameter        | Type    | Description                                           |
| ---------------- | ------- | ----------------------------------------------------- |
| `cipher`         | CIPHER  | Encryption algorithm: `aes128`, `aes192`, or `aes256` |
| `mode`           | MODE    | Block cipher mode: `cbc`, `ctr`, `gcm`, or `ccm`      |
| `padding`        | PADDING | Padding scheme: `pkcs7` or `nopad`                    |
| `key_hex`        | STRING  | Hex-encoded decryption key                            |
| `iv_hex`         | STRING  | Hex-encoded initialization vector or nonce            |
| `ciphertext_hex` | STRING  | Hex-encoded data to decrypt                           |

## Supported combinations

| Cipher | Mode | Padding | Key length | IV length | Tag length | Description     |
| ------ | ---- | ------- | ---------- | --------- | ---------- | --------------- |
| aes128 | cbc  | pkcs7   | 128 bits   | 128 bits  | —          | AES-128-CBC     |
| aes192 | cbc  | pkcs7   | 192 bits   | 128 bits  | —          | AES-192-CBC     |
| aes256 | cbc  | pkcs7   | 256 bits   | 128 bits  | —          | AES-256-CBC     |
| aes128 | cbc  | nopad   | 128 bits   | 128 bits  | —          | AES-128-CBC raw |
| aes192 | cbc  | nopad   | 192 bits   | 128 bits  | —          | AES-192-CBC raw |
| aes256 | cbc  | nopad   | 256 bits   | 128 bits  | —          | AES-256-CBC raw |
| aes128 | ctr  | nopad   | 128 bits   | 128 bits  | —          | AES-128-CTR     |
| aes192 | ctr  | nopad   | 192 bits   | 128 bits  | —          | AES-192-CTR     |
| aes256 | ctr  | nopad   | 256 bits   | 128 bits  | —          | AES-256-CTR     |
| aes128 | gcm  | nopad   | 128 bits   | 96 bits   | 128 bits   | AES-128-GCM     |
| aes192 | gcm  | nopad   | 192 bits   | 96 bits   | 128 bits   | AES-192-GCM     |
| aes256 | gcm  | nopad   | 256 bits   | 96 bits   | 128 bits   | AES-256-GCM     |
| aes128 | ccm  | nopad   | 128 bits   | 56 bits   | 96 bits    | AES-128-CCM     |
| aes192 | ccm  | nopad   | 192 bits   | 56 bits   | 96 bits    | AES-192-CCM     |
| aes256 | ccm  | nopad   | 256 bits   | 56 bits   | 96 bits    | AES-256-CCM     |

## Basic example

```vcl
declare local var.key_hex STRING;
declare local var.iv_hex STRING;
declare local var.ciphertext_hex STRING;
declare local var.plaintext_hex STRING;

set var.key_hex = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
set var.iv_hex = "000102030405060708090a0b";
set var.ciphertext_hex = "63a00fb1aa0404e84f9d3cb8fead8ec1b41c21e94e6d6f964e020159d955ab5c";

set var.plaintext_hex = crypto.decrypt_hex(aes256, gcm, nopad, var.key_hex, var.iv_hex, var.ciphertext_hex);

if (fastly.error == "EBADDECRYPT") {
  error 403 "Decryption failed";
}
```

## Authentication tags

For authenticated modes (GCM and CCM), the ciphertext input must include the authentication tag appended to the encrypted data (128 bits / 32 hex characters for GCM, 96 bits / 24 hex characters for CCM). This tag is automatically appended by `crypto.encrypt_hex()` and verified during decryption.

If the authentication tag is invalid or the ciphertext has been tampered with, decryption will fail and `fastly.error` will be set to `EBADDECRYPT`.

## Decryption modes

### AES-GCM and AES-CCM

These authenticated modes verify the integrity of the ciphertext before returning the plaintext. If verification fails, no plaintext is returned and `fastly.error` is set to `EBADDECRYPT`. This protects against tampering and ensures the data was encrypted with the correct key.

### AES-CTR and AES-CBC

These unauthenticated modes will always produce output if the parameters are valid, even if the key is wrong or the ciphertext has been modified. There is no way to detect tampering or incorrect keys from the decryption result alone. Applications using these modes should implement their own integrity checks.

With AES-CBC and `nopad` padding, the ciphertext length must be a multiple of 128 bits (16 bytes, 32 hex characters). With `pkcs7` padding, invalid padding will cause decryption to fail with `EBADDECRYPT`.

## Errors

If the requirements for the given cipher and mode are not met, or if the hex-encoded arguments are not valid hex, then `fastly.error` will be set to `EINVAL`.

If decryption fails due to authentication tag verification (GCM, CCM) or invalid padding (CBC with pkcs7), then `fastly.error` will be set to `EBADDECRYPT`.

## Related content

- `crypto.encrypt_hex()` - Encrypt to hex-encoded data.
- `crypto.encrypt_base64()` - Encrypt with Base64 encoding.
- `crypto.decrypt_base64()` - Decrypt Base64-encoded data.
