Package com.unboundid.util
Class PassphraseEncryptedOutputStream
- java.lang.Object
-
- java.io.OutputStream
-
- com.unboundid.util.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 anOutputStream
implementation that will encrypt all data written to it with a key generated from a passphrase. Details about the encryption will be encapsulated in aPassphraseEncryptedStreamHeader
, which will typically be written to the underlying stream before any of the encrypted data, so that thePassphraseEncryptedInputStream
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 thePassphraseEncryptedInputStream
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 was still a supported Java version for the LDAP SDK at the time this class was created) 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.
-
-
Field Summary
Fields Modifier and Type Field Description static int
DEFAULT_AES_128_CIPHER_TYPE_ITERATION_COUNT
The default PBKDF2 iteration count that should be used for thePassphraseEncryptionCipherType.AES_128
cipher type.static int
DEFAULT_AES_256_CIPHER_TYPE_ITERATION_COUNT
The default PBKDF2 iteration count that should be used for thePassphraseEncryptionCipherType.AES_256
cipher type.static java.lang.String
PROPERTY_DEFAULT_AES_128_CIPHER_TYPE_ITERATION_COUNT
The name of a system property that can be used to override the default PBKDF2 iteration count for thePassphraseEncryptionCipherType.AES_128
cipher type.static java.lang.String
PROPERTY_DEFAULT_AES_256_CIPHER_TYPE_ITERATION_COUNT
The name of a system property that can be used to override the default PBKDF2 iteration count for thePassphraseEncryptionCipherType.AES_256
cipher type.
-
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(PassphraseEncryptedStreamHeader header, java.io.OutputStream wrappedOutputStream, boolean writeHeaderToStream)
Creates a new passphrase-encrypted output stream that wraps the provided output stream and reuses the same derived secret key as the given stream header (although with a newly computed initialization vector).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.
-
-
-
Field Detail
-
DEFAULT_AES_128_CIPHER_TYPE_ITERATION_COUNT
public static final int DEFAULT_AES_128_CIPHER_TYPE_ITERATION_COUNT
The default PBKDF2 iteration count that should be used for thePassphraseEncryptionCipherType.AES_128
cipher type.
-
DEFAULT_AES_256_CIPHER_TYPE_ITERATION_COUNT
public static final int DEFAULT_AES_256_CIPHER_TYPE_ITERATION_COUNT
The default PBKDF2 iteration count that should be used for thePassphraseEncryptionCipherType.AES_256
cipher type.
-
PROPERTY_DEFAULT_AES_128_CIPHER_TYPE_ITERATION_COUNT
@NotNull public static final java.lang.String PROPERTY_DEFAULT_AES_128_CIPHER_TYPE_ITERATION_COUNT
The name of a system property that can be used to override the default PBKDF2 iteration count for thePassphraseEncryptionCipherType.AES_128
cipher type.
-
PROPERTY_DEFAULT_AES_256_CIPHER_TYPE_ITERATION_COUNT
@NotNull public static final java.lang.String PROPERTY_DEFAULT_AES_256_CIPHER_TYPE_ITERATION_COUNT
The name of a system property that can be used to override the default PBKDF2 iteration count for thePassphraseEncryptionCipherType.AES_256
cipher type.
-
-
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 generatedPassphraseEncryptedStreamHeader
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 benull
.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 benull
.- 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 generatedPassphraseEncryptedStreamHeader
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 benull
.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 benull
.- 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 benull
.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 benull
.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 benull
if no key identifier is needed.useStrongEncryption
- Indicates whether to attempt to use strong encryption, if it is available. If this istrue
and the JVM supports the stronger level of encryption, then that encryption will be used. If this isfalse
, 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 generatedPassphraseEncryptedStreamHeader
to the providedwrappedOutputStream
before any encrypted data so that aPassphraseEncryptedInputStream
can read it to obtain information necessary for decrypting the data. If this isfalse
, then thegetEncryptionHeader()
method must be used to obtain the encryption header so that it can be stored elsewhere and provided to thePassphraseEncryptedInputStream
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 benull
.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 benull
.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 benull
if no key identifier is needed.useStrongEncryption
- Indicates whether to attempt to use strong encryption, if it is available. If this istrue
and the JVM supports the stronger level of encryption, then that encryption will be used. If this isfalse
, 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 generatedPassphraseEncryptedStreamHeader
to the providedwrappedOutputStream
before any encrypted data so that aPassphraseEncryptedInputStream
can read it to obtain information necessary for decrypting the data. If this isfalse
, then thegetEncryptionHeader()
method must be used to obtain the encryption header so that it can be stored elsewhere and provided to thePassphraseEncryptedInputStream
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 benull
.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 benull
.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 benull
if no key identifier is needed.useStrongEncryption
- Indicates whether to attempt to use strong encryption, if it is available. If this istrue
and the JVM supports the stronger level of encryption, then that encryption will be used. If this isfalse
, 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 generatedPassphraseEncryptedStreamHeader
to the providedwrappedOutputStream
before any encrypted data so that aPassphraseEncryptedInputStream
can read it to obtain information necessary for decrypting the data. If this isfalse
, then thegetEncryptionHeader()
method must be used to obtain the encryption header so that it can be stored elsewhere and provided to thePassphraseEncryptedInputStream
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 benull
.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 benull
.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 benull
if no key identifier is needed.useStrongEncryption
- Indicates whether to attempt to use strong encryption, if it is available. If this istrue
and the JVM supports the stronger level of encryption, then that encryption will be used. If this isfalse
, 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 generatedPassphraseEncryptedStreamHeader
to the providedwrappedOutputStream
before any encrypted data so that aPassphraseEncryptedInputStream
can read it to obtain information necessary for decrypting the data. If this isfalse
, then thegetEncryptionHeader()
method must be used to obtain the encryption header so that it can be stored elsewhere and provided to thePassphraseEncryptedInputStream
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 benull
.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 benull
.properties
- The properties to use when encrypting data. It must not benull
.- 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 benull
.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 benull
.properties
- The properties to use when encrypting data. It must not benull
.- 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 PassphraseEncryptedStreamHeader header, @NotNull java.io.OutputStream wrappedOutputStream, boolean writeHeaderToStream) throws java.security.GeneralSecurityException, java.io.IOException
Creates a new passphrase-encrypted output stream that wraps the provided output stream and reuses the same derived secret key as the given stream header (although with a newly computed initialization vector). This can dramatically reduce the cost of creating a new passphrase-encrypted output stream with the same underlying password and settings without the need to recompute the key.- Parameters:
header
- The existing passphrase-encrypted stream header that contains the details to use for the encryption. It must not benull
, and it must have an associated secret key.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 benull
.writeHeaderToStream
- Indicates whether to write the generatedPassphraseEncryptedStreamHeader
to the providedwrappedOutputStream
before any encrypted data so that aPassphraseEncryptedInputStream
can read it to obtain information necessary for decrypting the data. If this isfalse
, then thegetEncryptionHeader()
method must be used to obtain the encryption header so that it can be stored elsewhere and provided to thePassphraseEncryptedInputStream
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.
-
-
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 classjava.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 classjava.io.OutputStream
- Parameters:
b
- The array containing the data to be written. It must not benull
. 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 classjava.io.OutputStream
- Parameters:
b
- The array containing the data to be written. It must not benull
.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 theoffset
andlength
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 interfacejava.io.Flushable
- Overrides:
flush
in classjava.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 interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
- Overrides:
close
in classjava.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 thePassphraseEncryptedInputStream
constructor.- Returns:
- An encryption header with details about the encryption being used.
-
-