public final class AesCtrHmacStreaming extends Object
Each ciphertext uses a new AES-CTR key and HMAC key that are derived from the key derivation key, a randomly chosen salt of the same size as the key and a nonce prefix using HKDF.
The format of a ciphertext is header || segment_0 || segment_1 || ... || segment_k. The header has size this.getHeaderLength(). Its format is headerLength || salt || prefix. where headerLength is 1 byte determining the size of the header, salt is a salt used in the key derivation and prefix is the prefix of the nonce. In principle headerLength is redundant information, since the length of the header can be determined from the key size.
segment_i is the i-th segment of the ciphertext. The size of segment_1 .. segment_{k-1} is ciphertextSegmentSize. segment_0 is shorter, so that segment_0, the header and other information of size firstSegmentOffset align with ciphertextSegmentSize.
| Modifier and Type | Field and Description |
|---|---|
static TinkFipsUtil.AlgorithmFipsCompatibility |
FIPS |
| Constructor and Description |
|---|
AesCtrHmacStreaming(byte[] ikm,
String hkdfAlgo,
int keySizeInBytes,
String tagAlgo,
int tagSizeInBytes,
int ciphertextSegmentSize,
int firstSegmentOffset)
Initializes a streaming primitive with a key derivation key and encryption parameters.
|
| Modifier and Type | Method and Description |
|---|---|
long |
expectedCiphertextSize(long plaintextSize)
Returns the expected size of the ciphertext for a given plaintext.
|
int |
getCiphertextOffset() |
int |
getCiphertextOverhead() |
int |
getCiphertextSegmentSize() |
int |
getFirstSegmentOffset() |
int |
getHeaderLength() |
int |
getPlaintextSegmentSize() |
ReadableByteChannel |
newDecryptingChannel(ReadableByteChannel ciphertextChannel,
byte[] associatedData) |
InputStream |
newDecryptingStream(InputStream ciphertextStream,
byte[] associatedData)
Returns a wrapper around
ciphertextSource, such that any read-operation
via the wrapper results in AEAD-decryption of the underlying ciphertext,
using associatedData as associated authenticated data. |
WritableByteChannel |
newEncryptingChannel(WritableByteChannel ciphertextChannel,
byte[] associatedData)
Returns a WritableByteChannel for plaintext.
|
OutputStream |
newEncryptingStream(OutputStream ciphertext,
byte[] associatedData)
Returns a wrapper around
ciphertextDestination, such that any write-operation via
the wrapper results in AEAD-encryption of the written data, using associatedData
as associated authenticated data. |
SeekableByteChannel |
newSeekableDecryptingChannel(SeekableByteChannel ciphertextSource,
byte[] associatedData)
Returns a SeekableByteChannel that allows to access the plaintext.
|
com.google.crypto.tink.subtle.AesCtrHmacStreaming.AesCtrHmacStreamDecrypter |
newStreamSegmentDecrypter() |
com.google.crypto.tink.subtle.AesCtrHmacStreaming.AesCtrHmacStreamEncrypter |
newStreamSegmentEncrypter(byte[] aad) |
public static final TinkFipsUtil.AlgorithmFipsCompatibility FIPS
public AesCtrHmacStreaming(byte[] ikm,
String hkdfAlgo,
int keySizeInBytes,
String tagAlgo,
int tagSizeInBytes,
int ciphertextSegmentSize,
int firstSegmentOffset)
throws GeneralSecurityException
ikm - input keying material used to derive sub keys.hkdfAlg - the JCE MAC algorithm name, e.g., HmacSha256, used for the HKDF key derivation.keySizeInBytes - the key size of the sub keystagAlgo - the JCE MAC algorithm name, e.g., HmacSha256, used for authentication.tagSizeInBytes - the size authentication tagsciphertextSegmentSize - the size of ciphertext segments.firstSegmentOffset - the offset of the first ciphertext segment. That means the first
segment has size ciphertextSegmentSize - getHeaderLength() - firstSegmentOffsetGeneralSecurityException - if called in FIPS mode.*InvalidAlgorithmParameterException - if ikm is too short, the key size not supported or
ciphertextSegmentSize is to short.public com.google.crypto.tink.subtle.AesCtrHmacStreaming.AesCtrHmacStreamEncrypter newStreamSegmentEncrypter(byte[] aad)
throws GeneralSecurityException
GeneralSecurityExceptionpublic com.google.crypto.tink.subtle.AesCtrHmacStreaming.AesCtrHmacStreamDecrypter newStreamSegmentDecrypter()
throws GeneralSecurityException
GeneralSecurityExceptionpublic int getCiphertextSegmentSize()
public int getPlaintextSegmentSize()
public int getHeaderLength()
public int getCiphertextOffset()
public int getCiphertextOverhead()
public int getFirstSegmentOffset()
public long expectedCiphertextSize(long plaintextSize)
public WritableByteChannel newEncryptingChannel(WritableByteChannel ciphertextChannel, byte[] associatedData) throws GeneralSecurityException, IOException
StreamingAeadciphertextDestinationnewEncryptingChannel in interface StreamingAeadciphertextChannel - the channel to which the ciphertext is written.associatedData - data associated with the plaintext. This data is authenticated
but not encrypted. It must be passed into the decryption.GeneralSecurityExceptionIOExceptionpublic ReadableByteChannel newDecryptingChannel(ReadableByteChannel ciphertextChannel, byte[] associatedData) throws GeneralSecurityException, IOException
newDecryptingChannel in interface StreamingAeadGeneralSecurityExceptionIOExceptionpublic SeekableByteChannel newSeekableDecryptingChannel(SeekableByteChannel ciphertextSource, byte[] associatedData) throws GeneralSecurityException, IOException
StreamingAeadThis method does not work on Android Marshmallow (API level 23) or older because these Android versions don't have the java.nio.channels.SeekableByteChannel interface.
newSeekableDecryptingChannel in interface StreamingAeadciphertextSource - the ciphertextassociatedData - the data associated with the ciphertext.SeekableByteChannel that allows random read access to the plaintext. The
following methods of SeekableByteChannel are implemented:
long position() Returns the channel's position in the plaintext.
SeekableByteChannel position(long newPosition) Sets the channel's position.
Setting the position to a value greater than the plaintext size is legal. A later
attempt to read byte will immediately return an end-of-file indication.
int read(ByteBuffer dst) Bytes are read starting at the channel's position,
and then the position is updated with the number of bytes actually read. All bytes
returned have been authenticated. If the end of the stream has been reached -1 is
returned. A result of -1 is authenticated (e.g. by checking the MAC of the last
ciphertext chunk.) A call to this function attempts to fill dst, but it may return
fewer bytes than requested, e.g. if the underlying ciphertextSource does not provide
the requested number of bytes or if the plaintext ended.
Throws IOException if a MAC verification failed. TODO: Should we extend
the interface with read(ByteBuffer dst, long position) to avoid race conditions?
long size() Returns the size of the plaintext. TODO: Decide whether the
result should be authenticated)
SeekableByteChannel truncate(long size) throws NonWritableChannelException because the channel is read-only.
int write(ByteBuffer src) throws NonWritableChannelException because the channel is read-only.
close() closes the channel
isOpen()
GeneralSecurityException - if the header of the ciphertext is corrupt or if
associatedData is not correct.IOException - if an IOException occurred while reading from ciphertextDestination.public OutputStream newEncryptingStream(OutputStream ciphertext, byte[] associatedData) throws GeneralSecurityException, IOException
StreamingAeadciphertextDestination, such that any write-operation via
the wrapper results in AEAD-encryption of the written data, using associatedData
as associated authenticated data. The associated data is not included in the ciphertext
and has to be passed in as parameter for decryption.newEncryptingStream in interface StreamingAeadGeneralSecurityExceptionIOExceptionpublic InputStream newDecryptingStream(InputStream ciphertextStream, byte[] associatedData) throws GeneralSecurityException, IOException
StreamingAeadciphertextSource, such that any read-operation
via the wrapper results in AEAD-decryption of the underlying ciphertext,
using associatedData as associated authenticated data.
The returned InputStream may support mark()/reset(),
but does not have to do it -- markSupported() provides the corresponding info.
The returned InputStream supports skip(), yet possibly in an inefficient way,
i.e. by reading a sequence of blocks until the desired position. If a more efficient
skip()-functionality is needed, the Channel-based API can be used.
newDecryptingStream in interface StreamingAeadGeneralSecurityExceptionIOException