Class SalmonStream

java.lang.Object
com.mku.streams.RandomAccessStream
com.mku.salmon.streams.SalmonStream

public class SalmonStream extends RandomAccessStream
Stream decorator provides AES256 encryption and decryption of stream. Block data integrity is also supported.
  • Nested Class Summary

    Nested classes/interfaces inherited from class com.mku.streams.RandomAccessStream

    RandomAccessStream.SeekOrigin
  • Constructor Summary

    Constructors
    Constructor
    Description
    SalmonStream(byte[] key, byte[] nonce, EncryptionMode encryptionMode, RandomAccessStream baseStream)
    Instantiate a new Salmon stream with a plain base stream.
    SalmonStream(byte[] key, byte[] nonce, EncryptionMode encryptionMode, RandomAccessStream baseStream, byte[] headerData)
    Instantiate a new Salmon stream with a base stream and embedded header data.
    SalmonStream(byte[] key, byte[] nonce, EncryptionMode encryptionMode, RandomAccessStream baseStream, byte[] headerData, boolean integrity, Integer chunkSize, byte[] hashKey)
    Instantiate a new Salmon stream with a base stream and optional header data and hash integrity.
  • Method Summary

    Modifier and Type
    Method
    Description
    long
    Provides the total length of the base stream including header and integrity data if available.
    boolean
    If the stream is readable (only if EncryptionMode == Decrypted)
    boolean
    If the stream is seekable (supported only if base stream is seekable).
    boolean
    If the stream is writable (only if EncryptionMode is Encrypt)
    void
    Closes the stream and all resources associated with it (including the base stream).
    void
    Flushes any buffered data to the base stream.
    static long
    getActualSize(byte[] data, byte[] key, byte[] nonce, EncryptionMode mode, byte[] headerData, boolean integrity, Integer chunkSize, byte[] hashKey)
    Get the output size of the data to be transformed(encrypted or decrypted) including header and hash without executing any operations.
    Get the global AES provider type.
    long
    Returns the current block value
    int
    Get the internal buffer size.
    int
    Returns the chunk size used to apply hash signature
    byte[]
    Returns the current Counter value.
    Get the encryption mode see EncryptionMode.
    byte[]
    Returns a copy of the hash key.
    byte[]
    Returns a copy of the encryption key.
    byte[]
    Returns a copy of the nonce.
    long
    Provides the position of the stream relative to the data to be transformed.
    boolean
    If the stream has integrity embedded.
    boolean
    Get the allowed range write option.
    boolean
    True if the stream has integrity enabled.
    long
    Provides the length of the actual transformed data (minus the header and integrity data).
    int
    read(byte[] buffer, int offset, int count)
    Decrypts the data from the baseStream and stores them in the buffer provided.
    long
    seek(long offset, RandomAccessStream.SeekOrigin origin)
    Seek to a specific position on the stream.
    static void
    Set the global AES provider type.
    void
    setAllowRangeWrite(boolean value)
    Warning! Allow byte range encryption writes on a current stream.
    void
    setBufferSize(int bufferSize)
    Set the internal buffer size.
    void
    setFailSilently(boolean value)
    Set to True if you want the stream to fail silently when integrity cannot be verified.
    void
    setLength(long value)
    Set the length of the base stream.
    void
    setPosition(long value)
    Sets the current position of the stream relative to the data to be transformed.
    void
    write(byte[] buffer, int offset, int count)
    Encrypts the data from the buffer and writes the result to the baseStream.

    Methods inherited from class com.mku.streams.RandomAccessStream

    copyTo, copyTo, copyTo

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • SalmonStream

      public SalmonStream(byte[] key, byte[] nonce, EncryptionMode encryptionMode, RandomAccessStream baseStream) throws IOException
      Instantiate a new Salmon stream with a plain base stream.
      Parameters:
      key - The AES encryption key.
      nonce - The nonce key.
      encryptionMode - The mode to use for encryption or decryption. This can only be set once.
      baseStream - If EncryptionMode is Encrypt this will be the target stream that data will be written to. If DecryptionMode is Decrypt this will be the source stream to read the data from.
      Throws:
      SalmonSecurityException - If the stream cannot be decrypted or missing key or nonce.
      IntegrityException - If the integrity of the stream is compromised.
      IOException - If the base stream is corrupt.
    • SalmonStream

      public SalmonStream(byte[] key, byte[] nonce, EncryptionMode encryptionMode, RandomAccessStream baseStream, byte[] headerData) throws IOException
      Instantiate a new Salmon stream with a base stream and embedded header data.
      Parameters:
      key - The key
      nonce - The nonce to use
      encryptionMode - The encryption Mode see EncryptionMode
      baseStream - If EncryptionMode is Encrypt this will be the target stream that data will be written to. If DecryptionMode is Decrypt this will be the source stream to read the data from.
      headerData - The header data to embed if you use EncryptionMode = Encrypt.
      Throws:
      SalmonSecurityException - If the stream cannot be decrypted or missing key or nonce.
      IntegrityException - If the integrity of the stream is compromised.
      IOException - If the base stream is corrupt.
    • SalmonStream

      public SalmonStream(byte[] key, byte[] nonce, EncryptionMode encryptionMode, RandomAccessStream baseStream, byte[] headerData, boolean integrity, Integer chunkSize, byte[] hashKey) throws IOException
      Instantiate a new Salmon stream with a base stream and optional header data and hash integrity.

      If you read from the stream it will decrypt the data from the baseStream. If you write to the stream it will encrypt the data from the baseStream. The transformation is based on AES CTR Mode.

      Notes: The initial value of the counter is a result of the concatenation of an 12 byte nonce and an additional 4 bytes counter. The counter is then: incremented every block, encrypted by the key, and xored with the plain text.
      Parameters:
      key - The AES key that is used to encrypt decrypt
      nonce - The nonce used for the initial counter
      encryptionMode - Encryption mode Encrypt or Decrypt this cannot change later
      baseStream - The base Stream that will be used to read the data
      headerData - The data to store in the header when encrypting.
      integrity - enable integrity
      chunkSize - the chunk size to be used with integrity
      hashKey - Hash key to be used with integrity
      Throws:
      IOException - Thrown if there is an IO error.
      SalmonSecurityException - Thrown if there is a security exception
      IntegrityException - Thrown if the data are corrupt or tampered with.
      See Also:
  • Method Details

    • getActualSize

      public static long getActualSize(byte[] data, byte[] key, byte[] nonce, EncryptionMode mode, byte[] headerData, boolean integrity, Integer chunkSize, byte[] hashKey) throws IOException
      Get the output size of the data to be transformed(encrypted or decrypted) including header and hash without executing any operations. This can be used to prevent over-allocating memory where creating your output buffers.
      Parameters:
      data - The data to be transformed.
      key - The AES key.
      nonce - The nonce for the CTR.
      mode - The EncryptionMode Encrypt or Decrypt.
      headerData - The header data to be embedded if you use Encryption.
      integrity - True if you want to enable integrity.
      chunkSize - The chunk size for integrity chunks.
      hashKey - The hash key to be used for integrity checks.
      Returns:
      The size of the output data.
      Throws:
      SalmonSecurityException - Thrown if there is a security exception
      IntegrityException - Thrown if the data are corrupt or tampered with.
      IOException - Thrown if there is an IO error.
    • setAesProviderType

      public static void setAesProviderType(ProviderType providerType)
      Set the global AES provider type. Supported types: ProviderType.
      Parameters:
      providerType - The provider Type.
    • getAesProviderType

      public static ProviderType getAesProviderType()
      Get the global AES provider type. Supported types: ProviderType.
      Returns:
      The provider Type.
    • length

      public long length()
      Provides the length of the actual transformed data (minus the header and integrity data).
      Specified by:
      length in class RandomAccessStream
      Returns:
      The length of the stream.
    • actualLength

      public long actualLength()
      Provides the total length of the base stream including header and integrity data if available.
      Returns:
      The actual length of the base stream.
    • getPosition

      public long getPosition() throws IOException
      Provides the position of the stream relative to the data to be transformed.
      Specified by:
      getPosition in class RandomAccessStream
      Returns:
      The current position of the stream.
      Throws:
      IOException - Thrown if there is an IO error.
    • setPosition

      public void setPosition(long value) throws IOException
      Sets the current position of the stream relative to the data to be transformed.
      Specified by:
      setPosition in class RandomAccessStream
      Parameters:
      value - The new position
      Throws:
      IOException - Thrown if there is an IO error.
    • canRead

      public boolean canRead()
      If the stream is readable (only if EncryptionMode == Decrypted)
      Specified by:
      canRead in class RandomAccessStream
      Returns:
      True if mode is decryption.
    • canSeek

      public boolean canSeek()
      If the stream is seekable (supported only if base stream is seekable).
      Specified by:
      canSeek in class RandomAccessStream
      Returns:
      True if stream is seekable.
    • canWrite

      public boolean canWrite()
      If the stream is writable (only if EncryptionMode is Encrypt)
      Specified by:
      canWrite in class RandomAccessStream
      Returns:
      True if mode is decryption.
    • hasIntegrity

      public boolean hasIntegrity()
      If the stream has integrity embedded.
      Returns:
      True if the stream has integrity embedded.
    • seek

      public long seek(long offset, RandomAccessStream.SeekOrigin origin) throws IOException
      Seek to a specific position on the stream. This does not include the header and any hash Signatures.
      Specified by:
      seek in class RandomAccessStream
      Parameters:
      offset - The offset that seek will use
      origin - If it is Begin the offset will be the absolute position from the start of the stream If it is Current the offset will be added to the current position of the stream If it is End the offset will be the absolute position starting from the end of the stream.
      Returns:
      The position after the seeking was complete.
      Throws:
      IOException - Thrown if there is an IO error.
    • setLength

      public void setLength(long value)
      Set the length of the base stream. Currently unsupported.
      Specified by:
      setLength in class RandomAccessStream
      Parameters:
      value - The new length
    • flush

      public void flush()
      Flushes any buffered data to the base stream.
      Specified by:
      flush in class RandomAccessStream
    • close

      public void close() throws IOException
      Closes the stream and all resources associated with it (including the base stream).
      Specified by:
      close in class RandomAccessStream
      Throws:
      IOException - Thrown if there is an IO error.
    • getCounter

      public byte[] getCounter()
      Returns the current Counter value.
      Returns:
      The current Counter value.
    • getBlock

      public long getBlock()
      Returns the current block value
      Returns:
      The current block
    • getKey

      public byte[] getKey()
      Returns a copy of the encryption key.
      Returns:
      The current key
    • getHashKey

      public byte[] getHashKey()
      Returns a copy of the hash key.
      Returns:
      The current hash key
    • getNonce

      public byte[] getNonce()
      Returns a copy of the nonce.
      Returns:
      The nonce.
    • getChunkSize

      public int getChunkSize()
      Returns the chunk size used to apply hash signature
      Returns:
      The chunk size
    • setAllowRangeWrite

      public void setAllowRangeWrite(boolean value)
      Warning! Allow byte range encryption writes on a current stream. Overwriting is not a good idea because it will re-use the same IV. This is not recommended if you use the stream on storing files or generally data if prior version can be inspected by others. You should only use this setting for initial encryption with parallel streams and not for overwriting!
      Parameters:
      value - True to allow byte range encryption write operations
    • setFailSilently

      public void setFailSilently(boolean value)
      Set to True if you want the stream to fail silently when integrity cannot be verified. In that case read() operations will return -1 instead of raising an exception. This prevents 3rd party code like media players from crashing.
      Parameters:
      value - True to fail silently.
    • read

      public int read(byte[] buffer, int offset, int count) throws IOException
      Decrypts the data from the baseStream and stores them in the buffer provided.
      Specified by:
      read in class RandomAccessStream
      Parameters:
      buffer - The buffer that the data will be stored after decryption
      offset - The start position on the buffer that data will be written.
      count - The requested count of the data bytes that should be decrypted
      Returns:
      The number of data bytes that were decrypted.
      Throws:
      IOException - Thrown if there is an IO error.
    • write

      public void write(byte[] buffer, int offset, int count) throws IOException
      Encrypts the data from the buffer and writes the result to the baseStream. If you are using integrity you will need to align all write operations to the chunk size otherwise align to the encryption block size.
      Specified by:
      write in class RandomAccessStream
      Parameters:
      buffer - The buffer that contains the data that will be encrypted
      offset - The offset in the buffer that the bytes will be encrypted.
      count - The length of the bytes that will be encrypted.
      Throws:
      IOException - Thrown if there is an IO error.
    • isIntegrityEnabled

      public boolean isIntegrityEnabled()
      True if the stream has integrity enabled.
      Returns:
      True if integrity is enabled
    • getEncryptionMode

      public EncryptionMode getEncryptionMode()
      Get the encryption mode see EncryptionMode.
      Returns:
      The encryption mode
    • isAllowRangeWrite

      public boolean isAllowRangeWrite()
      Get the allowed range write option. This can check if you can use random access write. This is generally not a good option since it prevents reusing the same nonce/counter.
      Returns:
      True if the stream allowed to seek and write.
    • getBufferSize

      public int getBufferSize()
      Get the internal buffer size.
      Returns:
      The buffer size
    • setBufferSize

      public void setBufferSize(int bufferSize)
      Set the internal buffer size.
      Parameters:
      bufferSize - The new buffer size