bb.io
Class EncryptUtil

java.lang.Object
  extended by bb.io.EncryptUtil

public final class EncryptUtil
extends Object

This class provides static utility methods for encryption. A main allows this program to also be used as a standalone command line application, especially useful for batch encryption and decryption operations (e.g. as part of a nightly backup process).

This class is multithread safe: it is immutable (both its immediate state, as well as the deep state of its fields).

Author:
Brent Boyer
See Also:
RSA paper on PBE, Many hash functions like MD5 and SHA0 are now compromised, Java for Symmetric Cryptography, JCE documentation, Bouncy Castle, What is best algorithm for PBE? Does 3DES still cut it? AES avail?, The DEFINITIVE thread on secure password entry (console, gui, code reviews), "bbLibrary/doc/encryptionNotes.txt"

Nested Class Summary
static class EncryptUtil.UnitTest
          See the Overview page of the project's javadocs for a general description of this unit test class.
 
Field Summary
private static String algorithm_key
           
static String decryptOperation
          Specifies decryption mode.
static String encryptionAlgorithm_default
          Stores a suggested encryption algorithm which classes that do not want to think about details can simply use.
static String encryptOperation
          Specifies encryption mode.
private static String fileInput_key
           
private static String fileIterationCount_key
           
private static String fileOutput_key
           
private static String fileSaltSource_key
           
private static String fileSaltTarget_key
           
private static List<String> keysLegal
          Specifies all the switch keys which can legally appear as command line arguments to main.
private static String operation_key
           
private static String password_key
           
private static String passwordInstruction_key
           
private static String secureRandomAlgorithm_default
           
 
Constructor Summary
private EncryptUtil()
          This sole private constructor suppresses the default (public) constructor, ensuring non-instantiability outside of this class.
 
Method Summary
static void eraseChars(char[] buffer)
          If buffer is not null, fills buffer with space (' ') chars.
private static int extractOperation(Properties2 switches)
           
private static PBEKeySpec extractPbeKeySpec(Properties2 switches, PBEParameterSpec pbeParamSpec)
           
private static PBEParameterSpec extractPbeParameterSpec(Properties2 switches)
           
static String getAlgorithmsAvailable(String serviceName)
          Returns a new String which describes all the available algorithm names for seviceName.
static Cipher getPbeCipher(String algorithm, PBEKeySpec pbeKeySpec, PBEParameterSpec pbeParamSpec, int mode)
          Returns a Password Based Encryption (PBE) Cipher.
private static boolean isValidPassword(char[] password)
          Checks if the supplied password is valid.
static void main(String[] args)
          Encrypts or decrypts a target File into a destination file.
static byte[] randomBytes(int length)
          Returns a cryptographically strong pseudo-random sequence of bytes as an array.
static char[] readConsoleSecure(String format, Object... args)
          Reads and returns some sensitive piece of information (e.g. a password) from the Console in a secure manner (the user's typing will not be echoed).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

encryptionAlgorithm_default

public static final String encryptionAlgorithm_default
Stores a suggested encryption algorithm which classes that do not want to think about details can simply use.

Contract: is never blank.

See Also:
Constant Field Values

secureRandomAlgorithm_default

private static final String secureRandomAlgorithm_default
See Also:
Constant Field Values

fileInput_key

private static final String fileInput_key
See Also:
Constant Field Values

fileOutput_key

private static final String fileOutput_key
See Also:
Constant Field Values

operation_key

private static final String operation_key
See Also:
Constant Field Values

algorithm_key

private static final String algorithm_key
See Also:
Constant Field Values

fileSaltSource_key

private static final String fileSaltSource_key
See Also:
Constant Field Values

fileSaltTarget_key

private static final String fileSaltTarget_key
See Also:
Constant Field Values

fileIterationCount_key

private static final String fileIterationCount_key
See Also:
Constant Field Values

passwordInstruction_key

private static final String passwordInstruction_key
See Also:
Constant Field Values

password_key

private static final String password_key
See Also:
Constant Field Values

keysLegal

private static final List<String> keysLegal
Specifies all the switch keys which can legally appear as command line arguments to main.


encryptOperation

public static final String encryptOperation
Specifies encryption mode.

Contract: is never blank.

See Also:
Constant Field Values

decryptOperation

public static final String decryptOperation
Specifies decryption mode.

Contract: is never blank.

See Also:
Constant Field Values
Constructor Detail

EncryptUtil

private EncryptUtil()
This sole private constructor suppresses the default (public) constructor, ensuring non-instantiability outside of this class.

Method Detail

main

public static void main(String[] args)
Encrypts or decrypts a target File into a destination file.

The File to be encrypted/decrypted must have its path specified on the command line in the usual switch format as -fileInput insertPathHere. The destination file must have its path specified on the command line in the usual switch format as -fileOutput insertPathHere.

The operation to perform (encryption or decryption) must be specified on the command line in the usual switch format as -operation encrypt or -operation decrypt.

The Password Based Encryption algorithm name must be specified on the command line in the usual switch format as -algorithm insertAlgorithmNameHere.

The salt (a random byte[] which is used as part of Password Based Encryption) must be specified in one of the following ways:

  1. the command line switch -fileSaltSource insertPathHere means that the random salt bytes have previously been generated and stored in the specified file; they are to be read in and used here; usually this option is used for decryption, with the salt file having been generated as part of encryption
  2. the command line switch -fileSaltTarget insertPathHere means that the random salt bytes need to be generated and then stored in the specified file before being used here; usually this option is used as part of encryption--the salt must be saved in a file for future decryption
Note that there is no default salt stored in this class; this is absolutely required to thwart dictionary attacks. Instead, the above options strongly encourage new salt to be used for each round of encryption.

The iteration count (also part of Password Based Encryption) must be stored in a file whose path is specified on the command line in the usual switch format as -fileIterationCount insertPathHere. This file should be a text file which only contains the digits of the iteration count (e.g. "1000000" is valid contents; "1000000\n" is not as it contains a line end). Unlike the salt, it is not critical that the iteration count change, just that it be a sufficiently high value (e.g. > 1,000).

A password may optionally be specified on the command line in the usual switch format as -password insertPasswordHere.

If the password is not specified on the command line, then the user will be prompted to enter one on the console or in a GUI dialog. In this case, there should be some prompt text given to the user. This is specified on the command line in the usual switch format as -passwordInstruction insertPasswordInstructionsHere.

Warning: if supply the password via the command line in this manner, there is a loss in security (the password will be stored at one point in a String, not a char[], and so can never be blanked out after use). Supplying the password via command line is only advised when doing batch encryptions from a trusted machine (e.g. as part of an automated backed process).

If this method is this Java process's entry point (i.e. first main method), then its final action is a call to System.exit, which means that this method never returns; its exit code is 0 if it executes normally, 1 if it throws a Throwable (which will be caught and logged). Otherwise, this method returns and leaves the JVM running.


extractOperation

private static int extractOperation(Properties2 switches)
                             throws IllegalArgumentException
Throws:
IllegalArgumentException

extractPbeParameterSpec

private static PBEParameterSpec extractPbeParameterSpec(Properties2 switches)
                                                 throws IllegalArgumentException,
                                                        InterruptedException,
                                                        IllegalStateException,
                                                        IOException,
                                                        NoSuchAlgorithmException
Throws:
IllegalArgumentException
InterruptedException
IllegalStateException
IOException
NoSuchAlgorithmException

extractPbeKeySpec

private static PBEKeySpec extractPbeKeySpec(Properties2 switches,
                                            PBEParameterSpec pbeParamSpec)
                                     throws IOException,
                                            InterruptedException,
                                            InvocationTargetException
Throws:
IOException
InterruptedException
InvocationTargetException

isValidPassword

private static boolean isValidPassword(char[] password)
Checks if the supplied password is valid. Current implementation (subject to change) is that only null or zero-length passwords are invalid. Should add stronger checks in the future (e.g. R5), but problem is that want this program to be able to decrypt files from any source, and the encrypting party may have different password policies in place.

See Also:
JX Yan, A Blackwell, RJ Anderson, A Grant, The Memorability and Security of Passwords—Some Empirical Results

getPbeCipher

public static Cipher getPbeCipher(String algorithm,
                                  PBEKeySpec pbeKeySpec,
                                  PBEParameterSpec pbeParamSpec,
                                  int mode)
                           throws Exception
Returns a Password Based Encryption (PBE) Cipher.

The Cipher is initialized to algorithm and mode before being returned.

This method never returns null.

Throws:
Exception - (many varieties) if any problem occurs
See Also:
Password based encryption code examples from JCE documentation

readConsoleSecure

public static char[] readConsoleSecure(String format,
                                       Object... args)
                                throws IllegalStateException,
                                       IllegalFormatException,
                                       IOError
Reads and returns some sensitive piece of information (e.g. a password) from the Console in a secure manner (the user's typing will not be echoed).

Contract: this method never returns null.

Parameters:
format - a format string as described in Format String Syntax for the prompt text
args - arguments referenced by the format specifiers in the format string. If there are more arguments than format specifiers, the extra arguments are ignored. The maximum number of arguments is limited by the maximum dimension of a Java array as defined by the Java Virtual Machine Specification.
Throws:
IllegalStateException - if no Console is associated with this JVM; read no chars from the Console
IllegalFormatException - if format contains an illegal syntax, a format specifier that is incompatible with the given arguments, insufficient arguments given the format string, or other illegal conditions. For specification of all possible formatting errors, see this documentation.
IOError - if an I/O problem occurs
See Also:
java.io.Console is finally here!, Reading passwords without echoing their text

eraseChars

public static void eraseChars(char[] buffer)
If buffer is not null, fills buffer with space (' ') chars.


randomBytes

public static byte[] randomBytes(int length)
                          throws IllegalArgumentException,
                                 NoSuchAlgorithmException
Returns a cryptographically strong pseudo-random sequence of bytes as an array. A new SecureRandom instance, whose internal state is completely randomized, is used for each call.

Throws:
IllegalArgumentException - if length < 0
NoSuchAlgorithmException - if secureRandomAlgorithm_default is unavailable

getAlgorithmsAvailable

public static String getAlgorithmsAvailable(String serviceName)
                                     throws IllegalArgumentException
Returns a new String which describes all the available algorithm names for seviceName.

Throws:
IllegalArgumentException