Class AesGcmHkdfStreaming
- java.lang.Object
-
- com.google.crypto.tink.subtle.AesGcmHkdfStreaming
-
- All Implemented Interfaces:
StreamingAead
public final class AesGcmHkdfStreaming extends java.lang.ObjectStreaming encryption usingAES-GCMwithHKDFas key derivation function.Each ciphertext uses a new AES-GCM key that is derived from the key derivation key, a randomly chosen salt of the same size as the key and a nonce prefix.
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.
This class does not work on Android KitKat (API level 19) or older.
- Since:
- 1.1.0
-
-
Constructor Summary
Constructors Constructor Description AesGcmHkdfStreaming(byte[] ikm, java.lang.String hkdfAlg, int keySizeInBytes, int ciphertextSegmentSize, int firstSegmentOffset)Initializes a streaming primitive with a key derivation key and encryption parameters.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static StreamingAeadcreate(AesGcmHkdfStreamingKey key)longexpectedCiphertextSize(long plaintextSize)Returns the expected size of the ciphertext for a given plaintext.intgetCiphertextOffset()intgetCiphertextOverhead()intgetCiphertextSegmentSize()intgetFirstSegmentOffset()intgetHeaderLength()intgetPlaintextSegmentSize()java.nio.channels.ReadableByteChannelnewDecryptingChannel(java.nio.channels.ReadableByteChannel ciphertextChannel, byte[] associatedData)java.io.InputStreamnewDecryptingStream(java.io.InputStream ciphertextStream, byte[] associatedData)Returns a wrapper aroundciphertextSource, such that any read-operation via the wrapper results in AEAD-decryption of the underlying ciphertext, usingassociatedDataas associated authenticated data.java.nio.channels.WritableByteChannelnewEncryptingChannel(java.nio.channels.WritableByteChannel ciphertextChannel, byte[] associatedData)Returns a WritableByteChannel for plaintext.java.io.OutputStreamnewEncryptingStream(java.io.OutputStream ciphertext, byte[] associatedData)Returns a wrapper aroundciphertextDestination, such that any write-operation via the wrapper results in AEAD-encryption of the written data, usingassociatedDataas associated authenticated data.java.nio.channels.SeekableByteChannelnewSeekableDecryptingChannel(java.nio.channels.SeekableByteChannel ciphertextSource, byte[] associatedData)Returns a SeekableByteChannel that allows to access the plaintext.com.google.crypto.tink.subtle.AesGcmHkdfStreaming.AesGcmHkdfStreamDecrypternewStreamSegmentDecrypter()com.google.crypto.tink.subtle.AesGcmHkdfStreaming.AesGcmHkdfStreamEncrypternewStreamSegmentEncrypter(byte[] aad)
-
-
-
Constructor Detail
-
AesGcmHkdfStreaming
public AesGcmHkdfStreaming(byte[] ikm, java.lang.String hkdfAlg, int keySizeInBytes, int ciphertextSegmentSize, int firstSegmentOffset) throws java.security.InvalidAlgorithmParameterExceptionInitializes a streaming primitive with a key derivation key and encryption parameters.- Parameters:
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 keysciphertextSegmentSize- the size of ciphertext segments.firstSegmentOffset- the offset of the first ciphertext segment. That means the first segment has size ciphertextSegmentSize - getHeaderLength() - firstSegmentOffset- Throws:
java.security.InvalidAlgorithmParameterException- if ikm is too short, the key size not supported or ciphertextSegmentSize is to short.
-
-
Method Detail
-
create
public static StreamingAead create(AesGcmHkdfStreamingKey key) throws java.security.GeneralSecurityException
- Throws:
java.security.GeneralSecurityException
-
newStreamSegmentEncrypter
public com.google.crypto.tink.subtle.AesGcmHkdfStreaming.AesGcmHkdfStreamEncrypter newStreamSegmentEncrypter(byte[] aad) throws java.security.GeneralSecurityException- Throws:
java.security.GeneralSecurityException
-
newStreamSegmentDecrypter
public com.google.crypto.tink.subtle.AesGcmHkdfStreaming.AesGcmHkdfStreamDecrypter newStreamSegmentDecrypter() throws java.security.GeneralSecurityException- Throws:
java.security.GeneralSecurityException
-
getPlaintextSegmentSize
public int getPlaintextSegmentSize()
-
getCiphertextSegmentSize
public int getCiphertextSegmentSize()
-
getHeaderLength
public int getHeaderLength()
-
getCiphertextOffset
public int getCiphertextOffset()
-
getCiphertextOverhead
public int getCiphertextOverhead()
-
getFirstSegmentOffset
public int getFirstSegmentOffset()
-
expectedCiphertextSize
public long expectedCiphertextSize(long plaintextSize)
Returns the expected size of the ciphertext for a given plaintext. The returned value includes the header and offset.
-
newEncryptingChannel
public java.nio.channels.WritableByteChannel newEncryptingChannel(java.nio.channels.WritableByteChannel ciphertextChannel, byte[] associatedData) throws java.security.GeneralSecurityException, java.io.IOExceptionDescription copied from interface:StreamingAeadReturns a WritableByteChannel for plaintext. Any data written to the returned channel will be encrypted and the resulting ciphertext written to the providedciphertextDestination- Specified by:
newEncryptingChannelin interfaceStreamingAead- Parameters:
ciphertextChannel- 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.- Throws:
java.security.GeneralSecurityExceptionjava.io.IOException
-
newDecryptingChannel
public java.nio.channels.ReadableByteChannel newDecryptingChannel(java.nio.channels.ReadableByteChannel ciphertextChannel, byte[] associatedData) throws java.security.GeneralSecurityException, java.io.IOException- Specified by:
newDecryptingChannelin interfaceStreamingAead- Throws:
java.security.GeneralSecurityExceptionjava.io.IOException
-
newSeekableDecryptingChannel
public java.nio.channels.SeekableByteChannel newSeekableDecryptingChannel(java.nio.channels.SeekableByteChannel ciphertextSource, byte[] associatedData) throws java.security.GeneralSecurityException, java.io.IOExceptionDescription copied from interface:StreamingAeadReturns a SeekableByteChannel that allows to access the plaintext.This 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.
- Specified by:
newSeekableDecryptingChannelin interfaceStreamingAead- Parameters:
ciphertextSource- the ciphertextassociatedData- the data associated with the ciphertext.- Returns:
SeekableByteChannelthat 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
IOExceptionif 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)throwsNonWritableChannelExceptionbecause the channel is read-only.int write(ByteBuffer src)throwsNonWritableChannelExceptionbecause the channel is read-only.close()closes the channelisOpen()
- Throws:
java.security.GeneralSecurityException- if the header of the ciphertext is corrupt or if associatedData is not correct.java.io.IOException- if an IOException occurred while reading from ciphertextDestination.
-
newEncryptingStream
public java.io.OutputStream newEncryptingStream(java.io.OutputStream ciphertext, byte[] associatedData) throws java.security.GeneralSecurityException, java.io.IOExceptionDescription copied from interface:StreamingAeadReturns a wrapper aroundciphertextDestination, such that any write-operation via the wrapper results in AEAD-encryption of the written data, usingassociatedDataas associated authenticated data. The associated data is not included in the ciphertext and has to be passed in as parameter for decryption.- Specified by:
newEncryptingStreamin interfaceStreamingAead- Throws:
java.security.GeneralSecurityExceptionjava.io.IOException
-
newDecryptingStream
public java.io.InputStream newDecryptingStream(java.io.InputStream ciphertextStream, byte[] associatedData) throws java.security.GeneralSecurityException, java.io.IOExceptionDescription copied from interface:StreamingAeadReturns a wrapper aroundciphertextSource, such that any read-operation via the wrapper results in AEAD-decryption of the underlying ciphertext, usingassociatedDataas 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 efficientskip()-functionality is needed, the Channel-based API can be used.- Specified by:
newDecryptingStreamin interfaceStreamingAead- Throws:
java.security.GeneralSecurityExceptionjava.io.IOException
-
-