Class Cryptor
- See Also:
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final @NonNull StringThe name of the encryption method used by this class, according to the Java Security Standard Algorithm Names documentation.static final @NonNull Stringstatic final intThe default number of iterations to be used by the Argon2 key derivation function: 4.static final intstatic final intstatic final intThe default degree of parallelism to be used by the Argon2 key derivation function: 4.static final @NonNull PatternMatches the PHC string format for Argon2 password hints (i.e. without the password hash, which is used as a key for symmetric encryption).static final @NonNull Argon2VariantThe default variant of the Argon2 key derivation function:Argon2Variant.ARGON2_ID.static final @NonNull Argon2Versionstatic final intThe AES-GCM specification recommends that the initialisation vector should be 96 bits = 12 bytes long.static final intThe default length of the encryption secret: 32 bytes = 256 bits.private static final org.apache.logging.log4j.Loggerstatic final intThe length of the tag: 128 bits = 16 bytes. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic @NonNull SecretKeybytesToSecretKey(byte @NonNull [] key) Converts an encryption key in the form of a byte array to aSecretKeyobject.static @NonNull Cryptor.KeyDerivationResultderiveKeyFromPassword(byte @NonNull [] password) static @NonNull Cryptor.KeyDerivationResultderiveKeyFromPassword(byte @NonNull [] password, byte @NonNull [] salt) static @NonNull Cryptor.KeyDerivationResultderiveKeyFromPassword(byte @NonNull [] password, Argon2Configuration argon2Configuration, int length) Converts a given human-readable password into a key of the given length, using the Argon2 key derivation function.static @NonNull CipherTextstatic byte[]generateRandomBytes(int length) Securely creates an array of randomly generated bytes.static @NonNull HashingResulthash(byte @NonNull [] input) Hashes the given input using the Argon2 hash function with the default parameters:static @NonNull HashingResulthash(byte @NonNull [] input, @NonNull Argon2Configuration argon2Configuration) Hashes the given input using the Argon2 hash function with the parameters specified in the givenArgon2Configuration.
-
Field Details
-
LOG
private static final org.apache.logging.log4j.Logger LOG -
AES_ALGORITHM_NAME
The name of the encryption method used by this class, according to the Java Security Standard Algorithm Names documentation.- See Also:
-
ALGORITHM
-
KEY_SIZE_BYTES
public static final int KEY_SIZE_BYTESThe default length of the encryption secret: 32 bytes = 256 bits.- See Also:
-
TAG_LENGTH_BITS
public static final int TAG_LENGTH_BITSThe length of the tag: 128 bits = 16 bytes. See NIST SP 800-38D.- See Also:
-
INITIALISATION_VECTOR_BYTES
public static final int INITIALISATION_VECTOR_BYTESThe AES-GCM specification recommends that the initialisation vector should be 96 bits = 12 bytes long. Why not longer? Well:
You can use arbitrary length nonces with AES-GCM, but if you use nonces longer than 12 bytes, they get hashed into 12 bytes anyway, so it’s not a detail most people should concern themselves with.
- See Also:
-
ARGON2_MEMORY_KiB
public static final int ARGON2_MEMORY_KiB- See Also:
-
ARGON2_ITERATIONS
public static final int ARGON2_ITERATIONSThe default number of iterations to be used by the Argon2 key derivation function: 4.- See Also:
-
ARGON2_PARALLELISM
public static final int ARGON2_PARALLELISMThe default degree of parallelism to be used by the Argon2 key derivation function: 4.- See Also:
-
ARGON2_LENGTH_BYTES
-
ARGON2_VERSION
-
ARGON2_VARIANT
The default variant of the Argon2 key derivation function:Argon2Variant.ARGON2_ID. -
ARGON2_PASSWORD_PATTERN
Matches the PHC string format for Argon2 password hints (i.e. without the password hash, which is used as a key for symmetric encryption).
- See Also:
-
-
Constructor Details
-
Cryptor
public Cryptor()
-
-
Method Details
-
hash
@NonNull public static @NonNull HashingResult hash(byte @NonNull [] input) throws de.gustavblass.commons.exceptions.IllegalArgumentException Hashes the given input using the Argon2 hash function with the default parameters:
- Argon2 version:
Argon2Version.ARGON2_VERSION_19 - Memory size:
ARGON2_MEMORY_KiB - Number of iterations:
ARGON2_ITERATIONS - KnownDegree of parallelism:
ARGON2_PARALLELISM - Hash length:
KEY_SIZE_BYTES - Salt: A randomly generated byte array of length
ARGON2_LENGTH_BYTES
See RFC 9106 for details.
- Parameters:
input- The text that shall be hashed. Must not be empty.- Returns:
The Argon2 hash of the input text.
will beinvalid reference
HashingResult#getHash()256 bits in length.
- Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException- If the input is empty.
- Argon2 version:
-
hash
@NonNull public static @NonNull HashingResult hash(byte @NonNull [] input, @NonNull @NonNull Argon2Configuration argon2Configuration) throws de.gustavblass.commons.exceptions.IllegalArgumentException Hashes the given input using the Argon2 hash function with the parameters specified in the givenArgon2Configuration.- Parameters:
input- The text that shall be hashed. Must not be blank.argon2Configuration- The parameters that shall be passed to the hash function.- Returns:
- The [HashingResult#getHash() Argon2 hash] of the input text. Will be 256 bits in length.
- Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException- If the input is blank or if the Argon2Configuration is invalid.
-
bytesToSecretKey
@NonNull public static @NonNull SecretKey bytesToSecretKey(byte @NonNull [] key) throws de.gustavblass.commons.exceptions.IllegalArgumentException Converts an encryption key in the form of a byte array to aSecretKeyobject. Does not check if the key is a valid AES key. Does not modify the key.- Parameters:
key- The encryption secret as a byte array.- Returns:
- The encryption secret as a
SecretKeyobject. - Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException- If the provided key is not a valid AES key.
-
encrypt
@NonNull public static @NonNull CipherText encrypt(@NonNull @NonNull String plainText, byte @NonNull [] password) throws de.gustavblass.commons.exceptions.IllegalArgumentException, org.bouncycastle.openssl.EncryptionException Uses the AES encryption algorithm in GCM mode to encrypt a given plaintext with a given password and a randomly generated initialisation vector.- Parameters:
plainText- The secret message that shall be encrypted. Must not be blank.password- The human-readable password that shall be used to derive the encryption key. Must not be empty (but otherwise it is not checked if it is secure enough) and must not be shared with anyone. Recommended: CallPasswordGenerator.estimatePasswordStrength(char[])to check the strength of the password before using it for encryption. (According to Kerckhoffs' principle, the security of the encryption used must solely rely on the secrecy of the key, meaning that the caller is responsible for providing a secure password.)- Returns:
- The encrypted message as a
CipherTextobject. It will be virtually impossible to convert it back to the original message without the correct password. - Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException-If:
- The plaintext is blank.
- The password is empty.
- No valid AES key could be derived from the password.
- The cipher could not be initialised.
org.bouncycastle.openssl.EncryptionException- In case of any error conditions thought impossible (should never happen).
-
generateRandomBytes
public static byte[] generateRandomBytes(int length) Securely creates an array of randomly generated bytes. Suitable for use as a salt or initialisation vector.- Parameters:
length- How many bytes the array should contain. One byte is eight bits.- Returns:
- The randomly generated values. The array returned will be of the length specified.
-
deriveKeyFromPassword
@NonNull public static @NonNull Cryptor.KeyDerivationResult deriveKeyFromPassword(byte @NonNull [] password) throws de.gustavblass.commons.exceptions.IllegalArgumentException Converts a given human-readable password into a 256-bit key suitable for AES encryption, using the Argon2 key derivation function.
Default configuration
See RFC 9106 for details.
- Argon2 version:
Argon2Version.ARGON2_VERSION_19 - Memory size:
ARGON2_MEMORY_KiB - Number of iterations:
ARGON2_ITERATIONS - Known degree of parallelism:
ARGON2_PARALLELISM - Hash length:
KEY_SIZE_BYTES - Salt: A randomly generated byte array of length
ARGON2_LENGTH_BYTES
- Parameters:
password- The user-provided encryption secret that shall be converted into a key.- Returns:
A
Cryptor.KeyDerivationResultwith- The derived key as a byte array
(for security reasons)
of length
KEY_SIZE_BYTES. - The
Argon2Configurationwith the parameters that were used to derive the key.
- The derived key as a byte array
(for security reasons)
of length
- Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException- If no valid salt could be generated (should never happen).- See Also:
- Implementation Note:
The salt is generated using a cryptographically secure random number generator.
The key derivation function is Argon2 (instead of PBKDF2 or scrypt), because it is the winner of the Password Hashing Competition and is considered the state-of-the-art key derivation function.
- Argon2 version:
-
deriveKeyFromPassword
@NonNull public static @NonNull Cryptor.KeyDerivationResult deriveKeyFromPassword(byte @NonNull [] password, byte @NonNull [] salt) throws de.gustavblass.commons.exceptions.IllegalArgumentException Converts a given human-readable password into a 256-bit key suitable for AES encryption, using the Argon2 key derivation function.
Default configuration
See RFC 9106 for details.
- Argon2 version:
Argon2Version.ARGON2_VERSION_19 - Memory size:
ARGON2_MEMORY_KiB - Number of iterations:
ARGON2_ITERATIONS - Known degree of parallelism:
ARGON2_PARALLELISM - Hash length:
KEY_SIZE_BYTES
- Parameters:
password- The user-provided encryption secret that shall be converted into a key.salt- The nonce (number used once) that must be unique for each key. Use the same salt during decryption that was used during encryption, but never re-use a salt for different keys. MUST be a number of bytes from 4 to 2^(32)-1.- Returns:
A
Cryptor.KeyDerivationResultwith- the derived key as a byte array
(for security reasons)
of length
KEY_SIZE_BYTES. - the
Cryptor.KeyDerivationResult.argon2Configuration()with the parameters that were used to derive the key.
- the derived key as a byte array
(for security reasons)
of length
- Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException- If the salt is not of a valid length (seeArgon2Configuration.setSalt(byte[])- See Also:
- Implementation Note:
- The key derivation function is Argon2 (instead of PBKDF2 or scrypt), because it is the winner of the Password Hashing Competition and is considered the state-of-the-art key derivation function.
- Argon2 version:
-
deriveKeyFromPassword
@NonNull public static @NonNull Cryptor.KeyDerivationResult deriveKeyFromPassword(byte @NonNull [] password, Argon2Configuration argon2Configuration, int length) throws de.gustavblass.commons.exceptions.IllegalArgumentException Converts a given human-readable password into a key of the given length, using the Argon2 key derivation function.
See RFC 9106.
- Parameters:
password- The user-provided encryption secret that shall be converted into a key.argon2Configuration- The Argon2 parameters that shall be used to derive the key.length- The output size of the derived key. MUST be between 4 and 2^(32)-1.- Returns:
- The derived key as a byte array of the given length.
- Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException- If any of the parameters does not meet the requirements.- See Also:
- Implementation Note:
- The key derivation function is Argon2 (instead of PBKDF2 or scrypt), because it is the winner of the Password Hashing Competition and is considered the state-of-the-art key derivation function.
-