Package org.cryptacular
Class CiphertextHeader
java.lang.Object
org.cryptacular.CiphertextHeader
Cleartext header prepended to ciphertext providing data required for decryption.
Data format:
+---------+---------+---+----------+-------+------+
| Version | KeyName | 0 | NonceLen | Nonce | HMAC |
+---------+---------+---+----------+-------+------+
| |
+--- 4 ---+--- x ---+ 1 +--- 1 ----+-- y --+- 32 -+
Where fields are defined as follows:
- Version - Header version format as a negative number (4-byte integer). Current version is -2.
- KeyName - Symbolic key name encoded as UTF-8 bytes (variable length)
- 0 - Null byte signifying the end of the symbolic key name
- NonceLen - Nonce length in bytes (1-byte unsigned integer)
- Nonce - Nonce bytes (variable length)
- HMAC - HMAC-256 over preceding fields (32 bytes)
The last two fields provide support for multiple keys at the encryption provider. A common case for multiple keys is key rotation; by tagging encrypted data with a key name, an old key may be retrieved by name to decrypt outstanding data which will be subsequently re-encrypted with a new key.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final intSize of HMAC algorithm output in bytes.Function to resolve a key from a symbolic key name.private final StringHeader key name field value.private final intHeader length in bytes.private static final intMaximum key name length in bytes.private static final intMaximum nonce length in bytes.private final byte[]Header nonce field value.private static final intHeader version format. -
Constructor Summary
ConstructorsConstructorDescriptionCiphertextHeader(byte[] nonce, String keyName) Creates a new instance with a nonce and named key.CiphertextHeader(byte[] nonce, String keyName, Function<String, SecretKey> keyLookup) Creates a new instance with a nonce, named key and key lookup. -
Method Summary
Modifier and TypeMethodDescriptionprivate static booleanarraysEqual(byte[] a, int aOff, byte[] b, int bOff, int length) Determines if two byte array ranges are equal bytewise.protected intstatic CiphertextHeaderCreates a header from encrypted data containing a cleartext header prepended to the start.static CiphertextHeaderdecode(InputStream input, Function<String, SecretKey> keyLookup) Creates a header from encrypted data containing a cleartext header prepended to the start.private static <T> CiphertextHeaderdecodeInternal(T source, Function<String, SecretKey> keyLookup, Function<T, Integer> readIntFn, Function<T, Byte> readByteFn, BiConsumer<T, byte[]> readBytesConsumer) Internal header decoding routine.byte[]encode()Encodes the header into bytes.byte[]Encodes the header into bytes.Gets the encryption key name stored in the header.intGets the header length in bytes.byte[]getNonce()Gets the bytes of the nonce/IV.private static byte[]hmac(byte[] input, int offset, int length) Generates an HMAC-256 over the given input byte array.private static bytereadByte(InputStream input) Read a single byte from the input stream.private static intreadInto(InputStream input, byte[] output) Readoutput.lengthbytes from the input stream into the output buffer.
-
Field Details
-
VERSION
private static final int VERSIONHeader version format.- See Also:
-
HMAC_SIZE
private static final int HMAC_SIZESize of HMAC algorithm output in bytes.- See Also:
-
MAX_NONCE_LEN
private static final int MAX_NONCE_LENMaximum nonce length in bytes.- See Also:
-
MAX_KEYNAME_LEN
private static final int MAX_KEYNAME_LENMaximum key name length in bytes.- See Also:
-
nonce
private final byte[] nonceHeader nonce field value. -
keyName
Header key name field value. -
length
private final int lengthHeader length in bytes. -
keyLookup
Function to resolve a key from a symbolic key name.
-
-
Constructor Details
-
CiphertextHeader
Creates a new instance with a nonce and named key.- Parameters:
nonce- Nonce bytes.keyName- Key name.
-
CiphertextHeader
Creates a new instance with a nonce, named key and key lookup.- Parameters:
nonce- Nonce bytes.keyName- Key name.keyLookup- Key lookup function.
-
-
Method Details
-
getLength
public int getLength()Gets the header length in bytes.- Returns:
- Header length in bytes.
-
getNonce
public byte[] getNonce()Gets the bytes of the nonce/IV.- Returns:
- Nonce bytes.
-
getKeyName
Gets the encryption key name stored in the header.- Returns:
- Encryption key name.
-
encode
public byte[] encode()Encodes the header into bytes.- Returns:
- Byte representation of header.
-
encode
Encodes the header into bytes.- Parameters:
hmacKey- Key used to generate header HMAC.- Returns:
- Byte representation of header.
-
computeLength
protected int computeLength()- Returns:
- Length of this header encoded as bytes.
-
decode
public static CiphertextHeader decode(byte[] data, Function<String, SecretKey> keyLookup) throws EncodingExceptionCreates a header from encrypted data containing a cleartext header prepended to the start.- Parameters:
data- Encrypted data with prepended header data.keyLookup- Function used to look up the secret key from the symbolic key name in the header.- Returns:
- Decoded header.
- Throws:
EncodingException- when ciphertext header cannot be decoded.
-
decode
public static CiphertextHeader decode(InputStream input, Function<String, SecretKey> keyLookup) throws EncodingException, StreamExceptionCreates a header from encrypted data containing a cleartext header prepended to the start.- Parameters:
input- Input stream that is positioned at the start of ciphertext header data.keyLookup- Function used to look up the secret key from the symbolic key name in the header.- Returns:
- Decoded header.
- Throws:
EncodingException- when ciphertext header cannot be decoded.StreamException- on stream IO errors.
-
decodeInternal
private static <T> CiphertextHeader decodeInternal(T source, Function<String, SecretKey> keyLookup, Function<T, Integer> readIntFn, Function<T, Byte> readByteFn, BiConsumer<T, byte[]> readBytesConsumer) Internal header decoding routine.- Type Parameters:
T- Type of input source.- Parameters:
source- Source of header data (input stream or byte buffer).keyLookup- Function to look up key from symbolic key name in header.readIntFn- Function that produces a 4-byte integer from the input source.readByteFn- Function that produces a byte from the input source.readBytesConsumer- Function that fills a byte array from the input source.- Returns:
- Decoded header.
-
hmac
private static byte[] hmac(byte[] input, int offset, int length) Generates an HMAC-256 over the given input byte array.- Parameters:
input- Input bytes.offset- Starting position in input byte array.length- Number of bytes in input to consume.- Returns:
- HMAC as byte array.
-
readInto
Readoutput.lengthbytes from the input stream into the output buffer.- Parameters:
input- Input stream.output- Output buffer.- Returns:
- number of bytes read
- Throws:
StreamException- on stream IO errors.
-
readByte
Read a single byte from the input stream.- Parameters:
input- Input stream.- Returns:
- Byte read from input stream.
-
arraysEqual
private static boolean arraysEqual(byte[] a, int aOff, byte[] b, int bOff, int length) Determines if two byte array ranges are equal bytewise.- Parameters:
a- First array to compare.aOff- Offset into first array.b- Second array to compare.bOff- Offset into second array.length- Number of bytes to compare.- Returns:
- True if every byte in the given range is equal, false otherwise.
-