Class PassphraseEncryptedOutputStream

  • All Implemented Interfaces:
    java.io.Closeable, java.io.Flushable, java.lang.AutoCloseable

    @ThreadSafety(level=NOT_THREADSAFE)
    public final class PassphraseEncryptedOutputStream
    extends java.io.OutputStream
    This class provides an OutputStream implementation that will encrypt all data written to it with a key generated from a passphrase. Details about the encryption will be encapsulated in a PassphraseEncryptedStreamHeader, which will typically be written to the underlying stream before any of the encrypted data, so that the PassphraseEncryptedInputStream can read it to determine how to decrypt that data when provided with the same passphrase. However, it is also possible to store the encryption header elsewhere and provide it to the PassphraseEncryptedInputStream constructor so that that the underlying stream will only include encrypted data.

    The specific details of the encryption performed may change over time, but the information in the header should ensure that data encrypted with different settings can still be decrypted (as long as the JVM provides the necessary support for that encryption). The current implementation uses a baseline of 128-bit AES/CBC/PKCS5Padding using a key generated from the provided passphrase using the PBKDF2WithHmacSHA1 key factory algorithm (unfortunately, PBKDF2WithHmacSHA256 isn't available on Java 7, which is still a supported Java version for the LDAP SDK) with 16,384 iterations and a 128-bit (16-byte) salt. However, if the output stream is configured to use strong encryption, then it will attempt to use 256-bit AES/CBC/PKCS5Padding with a PBKDF2WithHmacSHA512 key factory algorithm with 131,072 iterations and a 128-bit salt. If the JVM does not support this level of encryption, then it will fall back to a key size of 128 bits and a key factory algorithm of PBKDF2WithHmacSHA1.

    Note that the use of strong encryption may require special configuration for some versions of the JVM (for example, installation of JCE unlimited strength jurisdiction policy files). If data encrypted on one system may need to be decrypted on another system, then you should make sure that all systems will support the stronger encryption option before choosing to use it over the baseline encryption option.
    • Constructor Summary

      Constructors 
      Constructor Description
      PassphraseEncryptedOutputStream​(char[] passphrase, java.io.OutputStream wrappedOutputStream)
      Creates a new passphrase-encrypted output stream with the provided information.
      PassphraseEncryptedOutputStream​(char[] passphrase, java.io.OutputStream wrappedOutputStream, PassphraseEncryptedOutputStreamProperties properties)
      Creates a new passphrase-encrypted output stream with the provided information.
      PassphraseEncryptedOutputStream​(char[] passphrase, java.io.OutputStream wrappedOutputStream, java.lang.String keyIdentifier, boolean useStrongEncryption, boolean writeHeaderToStream)
      Creates a new passphrase-encrypted output stream with the provided information.
      PassphraseEncryptedOutputStream​(char[] passphrase, java.io.OutputStream wrappedOutputStream, java.lang.String keyIdentifier, boolean useStrongEncryption, int keyFactoryIterationCount, boolean writeHeaderToStream)
      Creates a new passphrase-encrypted output stream with the provided information.
      PassphraseEncryptedOutputStream​(java.lang.String passphrase, java.io.OutputStream wrappedOutputStream)
      Creates a new passphrase-encrypted output stream with the provided information.
      PassphraseEncryptedOutputStream​(java.lang.String passphrase, java.io.OutputStream wrappedOutputStream, PassphraseEncryptedOutputStreamProperties properties)
      Creates a new passphrase-encrypted output stream with the provided information.
      PassphraseEncryptedOutputStream​(java.lang.String passphrase, java.io.OutputStream wrappedOutputStream, java.lang.String keyIdentifier, boolean useStrongEncryption, boolean writeHeaderToStream)
      Creates a new passphrase-encrypted output stream with the provided information.
      PassphraseEncryptedOutputStream​(java.lang.String passphrase, java.io.OutputStream wrappedOutputStream, java.lang.String keyIdentifier, boolean useStrongEncryption, int keyFactoryIterationCount, boolean writeHeaderToStream)
      Creates a new passphrase-encrypted output stream with the provided information.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void close()
      Closes this output stream, along with the underlying output stream.
      void flush()
      Flushes the underlying output stream so that any buffered encrypted output will be written to the underlying output stream, and also flushes the underlying output stream.
      PassphraseEncryptedStreamHeader getEncryptionHeader()
      Retrieves an encryption header with details about the encryption being used.
      void write​(byte[] b)
      Writes an encrypted representation of the contents of the provided byte array to the underlying output stream.
      void write​(byte[] b, int offset, int length)
      Writes an encrypted representation of the specified portion of the provided byte array to the underlying output stream.
      void write​(int b)
      Writes an encrypted representation of the provided byte to the underlying output stream.
      • Methods inherited from class java.io.OutputStream

        nullOutputStream
      • Methods inherited from class java.lang.Object

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

      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               java.lang.String passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information. It will not use a key identifier, will use the baseline encryption strength rather than attempting to use strong encryption, and it will write the generated PassphraseEncryptedStreamHeader to the underlying stream before writing any encrypted data.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               char[] passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information. It will not use a key identifier, will use the baseline encryption strength rather than attempting to use strong encryption, and it will write the generated PassphraseEncryptedStreamHeader to the underlying stream before writing any encrypted data.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               java.lang.String passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream,
                                               @Nullable
                                               java.lang.String keyIdentifier,
                                               boolean useStrongEncryption,
                                               boolean writeHeaderToStream)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        keyIdentifier - An optional identifier that may be used to associate the encryption details with information in another system. This is primarily intended for use in conjunction with UnboundID/Ping Identity products, but may be useful in other systems. It may be null if no key identifier is needed.
        useStrongEncryption - Indicates whether to attempt to use strong encryption, if it is available. If this is true and the JVM supports the stronger level of encryption, then that encryption will be used. If this is false, or if the JVM does not support the attempted stronger level of encryption, then the baseline configuration will be used.
        writeHeaderToStream - Indicates whether to write the generated PassphraseEncryptedStreamHeader to the provided wrappedOutputStream before any encrypted data so that a PassphraseEncryptedInputStream can read it to obtain information necessary for decrypting the data. If this is false, then the getEncryptionHeader() method must be used to obtain the encryption header so that it can be stored elsewhere and provided to the PassphraseEncryptedInputStream constructor.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               char[] passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream,
                                               @Nullable
                                               java.lang.String keyIdentifier,
                                               boolean useStrongEncryption,
                                               boolean writeHeaderToStream)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        keyIdentifier - An optional identifier that may be used to associate the encryption details with information in another system. This is primarily intended for use in conjunction with UnboundID/Ping Identity products, but may be useful in other systems. It may be null if no key identifier is needed.
        useStrongEncryption - Indicates whether to attempt to use strong encryption, if it is available. If this is true and the JVM supports the stronger level of encryption, then that encryption will be used. If this is false, or if the JVM does not support the attempted stronger level of encryption, then the baseline configuration will be used.
        writeHeaderToStream - Indicates whether to write the generated PassphraseEncryptedStreamHeader to the provided wrappedOutputStream before any encrypted data so that a PassphraseEncryptedInputStream can read it to obtain information necessary for decrypting the data. If this is false, then the getEncryptionHeader() method must be used to obtain the encryption header so that it can be stored elsewhere and provided to the PassphraseEncryptedInputStream constructor.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               java.lang.String passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream,
                                               @Nullable
                                               java.lang.String keyIdentifier,
                                               boolean useStrongEncryption,
                                               int keyFactoryIterationCount,
                                               boolean writeHeaderToStream)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        keyIdentifier - An optional identifier that may be used to associate the encryption details with information in another system. This is primarily intended for use in conjunction with UnboundID/Ping Identity products, but may be useful in other systems. It may be null if no key identifier is needed.
        useStrongEncryption - Indicates whether to attempt to use strong encryption, if it is available. If this is true and the JVM supports the stronger level of encryption, then that encryption will be used. If this is false, or if the JVM does not support the attempted stronger level of encryption, then the baseline configuration will be used.
        keyFactoryIterationCount - The iteration count to use when generating the encryption key from the provided passphrase.
        writeHeaderToStream - Indicates whether to write the generated PassphraseEncryptedStreamHeader to the provided wrappedOutputStream before any encrypted data so that a PassphraseEncryptedInputStream can read it to obtain information necessary for decrypting the data. If this is false, then the getEncryptionHeader() method must be used to obtain the encryption header so that it can be stored elsewhere and provided to the PassphraseEncryptedInputStream constructor.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               char[] passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream,
                                               @Nullable
                                               java.lang.String keyIdentifier,
                                               boolean useStrongEncryption,
                                               int keyFactoryIterationCount,
                                               boolean writeHeaderToStream)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        keyIdentifier - An optional identifier that may be used to associate the encryption details with information in another system. This is primarily intended for use in conjunction with UnboundID/Ping Identity products, but may be useful in other systems. It may be null if no key identifier is needed.
        useStrongEncryption - Indicates whether to attempt to use strong encryption, if it is available. If this is true and the JVM supports the stronger level of encryption, then that encryption will be used. If this is false, or if the JVM does not support the attempted stronger level of encryption, then the baseline configuration will be used.
        keyFactoryIterationCount - The iteration count to use when generating the encryption key from the provided passphrase.
        writeHeaderToStream - Indicates whether to write the generated PassphraseEncryptedStreamHeader to the provided wrappedOutputStream before any encrypted data so that a PassphraseEncryptedInputStream can read it to obtain information necessary for decrypting the data. If this is false, then the getEncryptionHeader() method must be used to obtain the encryption header so that it can be stored elsewhere and provided to the PassphraseEncryptedInputStream constructor.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               java.lang.String passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream,
                                               @NotNull
                                               PassphraseEncryptedOutputStreamProperties properties)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        properties - The properties to use when encrypting data. It must not be null.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
      • PassphraseEncryptedOutputStream

        public PassphraseEncryptedOutputStream​(@NotNull
                                               char[] passphrase,
                                               @NotNull
                                               java.io.OutputStream wrappedOutputStream,
                                               @NotNull
                                               PassphraseEncryptedOutputStreamProperties properties)
                                        throws java.security.GeneralSecurityException,
                                               java.io.IOException
        Creates a new passphrase-encrypted output stream with the provided information.
        Parameters:
        passphrase - The passphrase that will be used to generate the encryption key. It must not be null.
        wrappedOutputStream - The output stream to which the encrypted data (optionally preceded by a header with details about the encryption) will be written. It must not be null.
        properties - The properties to use when encrypting data. It must not be null.
        Throws:
        java.security.GeneralSecurityException - If a problem is encountered while initializing the encryption.
        java.io.IOException - If a problem is encountered while writing the encryption header to the underlying output stream.
    • Method Detail

      • write

        public void write​(int b)
                   throws java.io.IOException
        Writes an encrypted representation of the provided byte to the underlying output stream.
        Specified by:
        write in class java.io.OutputStream
        Parameters:
        b - The byte of data to be written. Only the least significant 8 bits of the value will be used, and the most significant 24 bits will be ignored.
        Throws:
        java.io.IOException - If a problem is encountered while encrypting the data or writing to the underlying output stream.
      • write

        public void write​(@NotNull
                          byte[] b)
                   throws java.io.IOException
        Writes an encrypted representation of the contents of the provided byte array to the underlying output stream.
        Overrides:
        write in class java.io.OutputStream
        Parameters:
        b - The array containing the data to be written. It must not be null. All bytes in the array will be written.
        Throws:
        java.io.IOException - If a problem is encountered while encrypting the data or writing to the underlying output stream.
      • write

        public void write​(@NotNull
                          byte[] b,
                          int offset,
                          int length)
                   throws java.io.IOException
        Writes an encrypted representation of the specified portion of the provided byte array to the underlying output stream.
        Overrides:
        write in class java.io.OutputStream
        Parameters:
        b - The array containing the data to be written. It must not be null.
        offset - The index in the array of the first byte to be written. It must be greater than or equal to zero, and less than the length of the provided array.
        length - The number of bytes to be written. It must be greater than or equal to zero, and the sum of the offset and length values must be less than or equal to the length of the provided array.
        Throws:
        java.io.IOException - If a problem is encountered while encrypting the data or writing to the underlying output stream.
      • flush

        public void flush()
                   throws java.io.IOException
        Flushes the underlying output stream so that any buffered encrypted output will be written to the underlying output stream, and also flushes the underlying output stream. Note that this call may not flush any data that has yet to be encrypted (for example, because the encryption uses a block cipher and the associated block is not yet full).
        Specified by:
        flush in interface java.io.Flushable
        Overrides:
        flush in class java.io.OutputStream
        Throws:
        java.io.IOException - If a problem is encountered while flushing data to the underlying output stream.
      • close

        public void close()
                   throws java.io.IOException
        Closes this output stream, along with the underlying output stream. Any remaining buffered data will be processed (including generating any necessary padding) and flushed to the underlying output stream before the streams are closed.
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Overrides:
        close in class java.io.OutputStream
        Throws:
        java.io.IOException - If a problem is encountered while closing the stream.
      • getEncryptionHeader

        @NotNull
        public PassphraseEncryptedStreamHeader getEncryptionHeader()
        Retrieves an encryption header with details about the encryption being used. If this header was not automatically written to the beginning of the underlying output stream before any encrypted data, then it must be stored somewhere else so that it can be provided to the PassphraseEncryptedInputStream constructor.
        Returns:
        An encryption header with details about the encryption being used.