crypto.encrypt_hex
Available inall subroutines.
Symmetric key encryption.
The cipher
parameter specifies both the cipher name (AES) and the
key size (128-bit, 192-bit, 256-bit).
The available ciphers are: aes128
, aes192
, aes256
.
The mode
parameter specifies the
mode of operation
for the given cipher.
ECB, CFB, and OFB modes are not provided, but are discussed here for context.
The available modes for AES are: cbc
, ctr
.
The padding
parameter specifies padding for block ciphers.
The available padding values are pkcs7
and nopad
for no padding.
When using ctr
mode, the padding must be set to nopad
.
When using CBC or ECB mode with padding set to nopad
, plaintext must
decode to raw data exactly equal in length to the block size for the
given cipher.
The key, Initialization Vector (IV), plaintext, and ciphertext are all
hex encoded strings. Hex values are case insensitive, and do not have
a leading 0x
prefix. For block ciphers, the IV must decode to raw
data of exactly equal in length to the block size for the given cipher
.
For modes that do not use an IV, the iv
parameter is passed either
a not set
value or an empty string.
AES CBC and CTR modes require the iv
parameter to be set.
For ciphers with a fixed key length, the key must decode to raw data
of a size exactly equal in length to the key size for the given cipher
.
Padding
CBC and ECB modes require that input exactly divides into a sequence of fixed-size blocks. This is ensured either by passing in data of the appropriate length, or by padding it to meet the size requirement. CTR, CFB and OFB modes do not have this requirement, so no padding is applied for those modes.
The parameter pkcs7
represents PKCS#7 as specified by
RFC 5652 §6.3.
This is identical to PKCS#5, except that PKCS#5 is only defined
for 64-bit block sizes and PKCS#7 is defined for any block size.
Block size depends on the cipher in use. AES has a block size of 16.
Padding will add the smallest number of bytes required to reach the next block size. This is always one byte at minimum. For example, an empty string will be padded to a single block, and data exactly the size of a single block will be padded to two blocks.
Key generation
The key_hex
and iv_hex
parameters are not verbatim passwords.
However these may be derived from passwords using a
key derivation function
such as PBKDF2 (specified by RFC 2898 §5.2).
An example showing using the OpenSSL command line tool to derive a 256-bit key and IV (both in hex) suitable for AES CBC:
$ openssl enc -nosalt -aes-256-cbc -pbkdf2 -k example -Pkey=7ECEA90030826D5326D2C61341B0C1FD02AEE6B58C2FC4D5C9552C50FCB0E44Div =F2F8B61408F67638B6FBEEB2348F0B5B
For ctr
mode, the iv
parameter serves as the CTR counter rather than
as an IV. The counter is subject to constraints in order to behave securely.
In particular a given counter value and key should not be reused in
combination to encrypt two plaintext data sets.
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 the wrong key or IV are used when decrypting with AES CBC,
then fastly.error
will be set to EBADDECRYPT
.
Decrypting with AES CTR cannot produce EBADDECRYPT
. For AES CTR,
decryption is the same as encrypting. Decrypting with the wrong
key will still produce a plaintext result, but it will contain
meaningless data.
Example
An example from NIST Special Publication 800-38A F.2.5, illustrating encrypting and decrypting an example vector using 256-bit AES CBC:
declare local var.key STRING;declare local var.iv STRING;declare local var.plaintext STRING; # hex encoded inputdeclare local var.ciphertext STRING; # hex encoded output
# NIST sample vector dataset var.key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; # 256-bitset var.iv = "000102030405060708090a0b0c0d0e0f"; # 16 bytesset var.plaintext = "6bc1bee22e409f96e93d7e117393172a";
unset fastly.error;
set var.ciphertext = crypto.encrypt_hex(aes256, cbc, nopad, var.key, var.iv, var.plaintext);# returns the 16-byte ciphertext "f58c4c04d6e5f1ba779eabfb5f7bfbd6"if (fastly.error) { error 503;}
set var.plaintext = crypto.decrypt_hex(aes256, cbc, nopad, var.key, var.iv, var.ciphertext);if (fastly.error == "EBADDECRYPT") { error 403 "Wrong key";} else if (fastly.error) { error 503;}
The same ciphertext may be confirmed by using the OpenSSL command line tool:
$ echo -n 6bc1bee22e409f96e93d7e117393172a \| xxd -r -p \| openssl enc -nosalt -nopad -aes-256-cbc \ -K 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 \ -iv 000102030405060708090a0b0c0d0e0f \| xxd -pf58c4c04d6e5f1ba779eabfb5f7bfbd6