Binary container format
jEAP Crypto stores encrypted data in a self-describing binary container that holds the wrapped data
key(s), the ciphertext and the metadata needed to decrypt it. The first byte is a format version
identifier that selects one of the formats below. All multi-byte numbers are big-endian (the
default of a Java ByteBuffer).
| Format id | Name | KMS | Description |
|---|---|---|---|
01 | Compact format | Vault | Encrypted data key + ciphertext only. The wrapping key is not stored; it must come from configuration |
02 | Key reference format | Vault | Adds a reference to the wrapping key (secret-engine path + key name), so the key is selectable at decryption time |
03 | Multi-key format | AWS KMS | Allows multiple wrapped data keys (e.g. KMS + escrow), each with a key reference. Always carries the key reference |
Which format is produced depends on the crypto service and KMS used: CryptoService on Vault uses the
compact format, KeyReferenceCryptoService / KeyIdCryptoService on Vault use the key reference
format, and AWS KMS always uses the multi-key format.
Compact format (01)
AES-256-GCM ciphertext with a single versioned data key; the wrapping key name/path is not persisted.
| Offset | Length | Content |
|---|---|---|
| 0 | 1 | Format version identifier (01) |
| 1 | 4 | Data-key wrapping-key version |
| 5 | 60 | Encrypted data key + auth tag + key nonce (as produced by Vault Transit) |
| 65 | 12 | Nonce (generated by jEAP Crypto, never repeated per data key) |
| 77 | variable | Encrypted data + auth tag |
Key reference format (02)
Like the compact format but with the wrapping key reference embedded, so the key can be determined
dynamically at decryption time. The leading length field gives the byte length of the UTF-8 encoded
reference (e.g. v:transit/jme:my-key), after which the version, encrypted data key, nonce and
ciphertext follow as in the compact format.
Multi-key format (03)
Supports one or more wrapped data keys, each preceded by its own block with a key-provider id, an
optional wrapping-key reference and the encrypted data key. This is how an escrow data key is
stored alongside the KMS-wrapped data key so the data can be recovered without the KMS. After the data
keys, a payload block carries an algorithm id (AES-256-GCM), the nonce and the encrypted data plus
auth tag. The format is intentionally generic to support different KMS backends and future algorithms.