Skip to main content

Format Preserving Encryption (FPE)

Use Vault for Format-Preserving Encryption (FPE) with keys created for FPE

FPE keeps the format of the input data in the encrypted output. Unlike traditional encryption methods that turn data into an unreadable string of a fixed length, FPE retains the original data length, character set per position, and structure, including the positions of delimiters and separators. For example, with FPE, the digits in a phone number can be encrypted, but the parentheses, spaces, and hyphens stay in their original positions.

Because FPE preserves the format of data, it can be used to retrofit security in existing systems, such as legacy databases and applications that expect data in a specific format. It also helps meet compliance requirements that mandate certain data formats and structures.

FPE is commonly used to protect Personally Identifiable Information (PII) such as social security numbers, phone numbers, and credit card numbers. FPE keeps the data compatible with existing systems and maintains its appearance in logs. Additionally, in the event of a data leak, an attacker might not realize the data is encrypted.

Note that while FPE preserves the format based on the selected alphabet, the encrypted value might appear nonsensical. For example, a name could turn into a random mix of uppercase and lowercase letters, or an IP address might become invalid.

You can create a key for Format Preserving Encryption with one of the supported FPE algorithms on Vault's Secrets & Keys page in the Pangea User Console.

Encrypt

You can use FPE keys to encrypt a single value by using Vault’s /v1/key/encrypt/transform endpoint.

Provide the following parameters:

  • id - The ID of a key designated for Format Preserving Encryption and stored in Vault
  • plain_text - The data to be encrypted
  • alphabet - A set of characters used for format-preserving encryption.

    Characters not included in the selected alphabet will remain unchanged in the encrypted output. The available choices are:

    • numeric - Numeric (0-9)
    • alphalower - Lowercase alphabet (a-z)
    • alphaupper - Uppercase alphabet (A-Z)
    • alpha - Lowercase and uppercase alphabet (a-z, A-Z)
    • alphanumericlower - Lowercase alphabet with numbers (a-z, 0-9)
    • alphanumericupper - Uppercase alphabet with numbers (A-Z, 0-9)
    • alphanumeric - Alphanumeric (a-z, A-Z, 0-9)

    For example, a driver's license with the original value "A1234567" could become "A4313639" if encrypted using the numeric alphabet. Note that the "A" is preserved as part of the format, but the digits are changed."

Optionally, you can specify:

  • tweak - A user-provided tweak string. If a tweak value is not provided, a random string will be generated and returned in the API response.

    A tweak is an additional input used alongside the plaintext and encryption key to enhance security. It makes it harder for attackers to use statistical methods to break the encryption. Different tweak values will produce different outputs for the same encryption key and data. The original tweak value used for encryption is required to decrypt the data.

    The tweak value will be returned in the response from the /v1/key/encrypt/transform endpoint. If you didn't provide a custom value, save the one that was returned during encryption to decrypt the output. If you need to know or share the tweak value before the encryption, use a custom one and save it in a safe place.

  • version - An integer representing the version of the key used for encryption. If you omit the version in the request parameters, the default (current) version will be used.

Example

export PANGEA_DOMAIN="aws.us.pangea.cloud"
export PANGEA_VAULT_TOKEN="pts_zi5orj...7c6c5l"
POST/v1/key/encrypt/transform
curl --location "https://vault.$PANGEA_DOMAIN/v1/key/encrypt/transform" \
--header "Authorization: Bearer $PANGEA_VAULT_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
  "id": "pvi_x7ommvlytd7hwsgpxcvczqu37mqpkpd5",
  "plain_text": "(555) 555-5555",
  "alphabet": "numeric"
}'

The encrypted message and the parameters used for encryption will be returned under the "result" key in the response:

/v1/key/encrypt/transform response
{
  "status": "Success",
  "summary": "Message encrypted",
  "result": {
    "algorithm": "AES-FF3-1-256-BETA",
    "alphabet": "numeric",
    "cipher_text": "(014) 731-9197",
    "id": "pvi_x7ommvlytd7hwsgpxcvczqu37mqpkpd5",
    "tweak": "LRnCHIa",
    "version": 1
  },
  ...
}
note

Using the same key version and tweak value will result in the same encrypted output:

POST/v1/key/encrypt/transform
curl --location "https://vault.$PANGEA_DOMAIN/v1/key/encrypt/transform" \
--header "Authorization: Bearer $PANGEA_VAULT_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
  "id": "pvi_x7ommvlytd7hwsgpxcvczqu37mqpkpd5",
  "plain_text": "(555) 555-5555",
  "alphabet": "numeric",
  "tweak": "LRnCHIa",
  "version": 1
}'
/v1/key/encrypt/transform response
{
  "status": "Success",
  "summary": "Message encrypted",
  "result": {
    "algorithm": "AES-FF3-1-256-BETA",
    "alphabet": "numeric",
    "cipher_text": "(014) 731-9197",
    "id": "pvi_x7ommvlytd7hwsgpxcvczqu37mqpkpd5",
    "tweak": "LRnCHIa",
    "version": 1
  },
  ...
}

Decrypt

To decrypt the encrypted message, provide the encrypted output and parameters used for encryption:

  • cipher_text - The message encrypted by Vault
  • id - The Vault key ID used for encrypting the message
  • alphabet - The set of characters used for encrypting the message
  • tweak - The tweak value used for encrypting the message

If your message was encrypted with a previous (non-current) version of the Vault key, you must provide that specific version number during decryption:

  • version - An integer representing the version of the key used for encryption. If you omit the version in the request parameters, the default (current) version will be used. If the provided version does not match the one used for encryption, the decryption of messages will fail.

    This situation may occur if the Vault key used for encryption has been rotated, and the current version no longer matches the key version used for encryption.

Example

export PANGEA_DOMAIN="aws.us.pangea.cloud"
export PANGEA_VAULT_TOKEN="pts_zi5orj...7c6c5l"
POST/v1/key/decrypt/transform
curl --location "https://vault.$PANGEA_DOMAIN/v1/key/decrypt/transform" \
--header "Authorization: Bearer $PANGEA_VAULT_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
  "id": "pvi_x7ommvlytd7hwsgpxcvczqu37mqpkpd5",
  "cipher_text": "(014) 731-9197",
  "alphabet": "numeric",
  "tweak": "LRnCHIa",
  "version": 1
}'

The decrypted message will be returned under result.plain_text in the response:

/v1/key/decrypt/transform response
{
  "status": "Success",
  "summary": "Message decrypted",
  "result": {
    "algorithm": "AES-FF3-1-256-BETA",
    "id": "pvi_x7ommvlytd7hwsgpxcvczqu37mqpkpd5",
    "plain_text": "(555) 555-5555",
    "tweak": "LRnCHIa",
    "version": 1
  },
  ...
}

Was this article helpful?

Contact us