net.goui.util
Class GoSecure

java.lang.Object
  extended bynet.goui.util.GoSecure

public final class GoSecure
extends java.lang.Object

Version:
1.0
Author:
David Beaumont (gosecure-at-goui.net), Copyright 2005

This class can be used to generate a deterministic sequence of strings suitable for use as passwords for web sites and other services. The sequences are uniquely defined by three primary pieces of information; the user name, the service string and a pass phrase. Other parameters can also be used to vary the length and construction of the strings.

The algorithm used to generate a sequence of strings is relatively simple and is based upon the use of three existing algorithms:

The hashing algorithm used is actually specified during the instantiation of a GoSecure instance. If code using this class is to be distributed to other Java runtime environments, care must be taken to ensure that the particular digest algorithm existing on all target devices.

While we could just generate a password from a hash of the given user name, service string and pass phrase, the pseudo random number generator is used to allow us to generate an effectively arbitrary sequence of passwords in order to improve our chances of obtaining a valid password when faced with an unexpected set of constraints for a particular service.

What we actually do is take a hash of the user name, service string and pass phrase and use that to seed the pseudo random number generator. We then use the output from the pseudo random number generator to create the sequence of passwords. To avoid losing any information in the PRNG an implementation of the Mersenne Twister algorithm (MT19937) is used. This algorithm has a period of 219937-1 and uses up to 624 words for its seed value. Note however that this algorithm is not cryptographically secure and it might be unwise to use it to generate very large sequences of passwords from the same hashed information.

Being insecure however does not compromise the security of your pass phrase because this has already been passed through a secure hashing algorithm before being used in the PRNG. The worst that could happen is that an attacker who already had a large number of passwords generated for a particular user name, service and passphrase might be able to determine the next password in the sequence. Under normal usage of this class you only generate one password for each user name, service and passphrase, so no advantage can be gained.

Having obtained our sequence of bytes from the PRNG we then go on to generate the password. Depending on the type of password chosen we select characters from a range of available character sets; lower-case, upper-case, numerals and symbolic characters can all be present. If a password is required for verbal use then the SPOKEN type can be selected which utilises an implementation of the GPW (Generate Pronounceable Passwords) algorithm by Tom Van Vleck. See http://www.multicians.org/thvv/gpw.html for more information.

That's about it really. If you wish to understand more about the algorithm or want to implement it in a different language for example then please contact me. The only thing that I would ask is that if you generate a similar algorithm that produces different passwords, you clearly state this in the documentation. I don't want people being confused by lots of incompatible versions of this algorithm out there.


Field Summary
static int ALPHANUM
          Enumeration for the alpha-numeric, [a-z]+[A-Z]+[0-9], password type.
static float[] BITS_PER_CHAR
           
static int LENGTH_MIN
          This is the minimum possible password length which can be produced by this class.
static int LOWER
          Enumeration for the lower-case, [a-z], password type.
static int MIXED
          Enumeration for the mixed-case, [a-z]+[A-Z], password type.
static int SALT_MAX
          This is the upper limit on the acceptable size of the salt string.
static int SPOKEN
          Enumeration for the English pronounceable (insecure) password type.
static int SYMBOL
          Enumeration for the symbolic (full printable ASCII) password type.
static int TYPE_MAX
          A convenience constant for use when range checking the type enumeration values.
static java.lang.String VERSION
          Simple version identifier which can be used to ensure compatibility between versions.
 
Constructor Summary
GoSecure(java.lang.String publicKey, java.lang.String privateKey, java.lang.String digest, int saltLength)
          Initialise an instance of GoSecure using the given key and hashing scheme.
 
Method Summary
 java.lang.String getPassword(int length, int type, int skip)
          Get the next available password conforming to the given constraints.
 java.lang.String getSalt()
          Returns the salt string constructed from the private key information.
 void reset()
          Resets the state of the password sequence to the same state as when this instance was first initialised.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

VERSION

public static final java.lang.String VERSION
Simple version identifier which can be used to ensure compatibility between versions. All versions of GoSecure with the same version String will produce the same sequences of passwords.

See Also:
Constant Field Values

SPOKEN

public static final int SPOKEN
Enumeration for the English pronounceable (insecure) password type.

The generation of these pronounceable passwords is based on the work by Tom Van Vleck and currently only supports data tables for the English language.

More information about the original pronounceable password algorithm can be found at http://www.multicians.org/thvv/gpw.html.

See Also:
Constant Field Values

LOWER

public static final int LOWER
Enumeration for the lower-case, [a-z], password type.

See Also:
Constant Field Values

MIXED

public static final int MIXED
Enumeration for the mixed-case, [a-z]+[A-Z], password type.

See Also:
Constant Field Values

ALPHANUM

public static final int ALPHANUM
Enumeration for the alpha-numeric, [a-z]+[A-Z]+[0-9], password type.

See Also:
Constant Field Values

SYMBOL

public static final int SYMBOL
Enumeration for the symbolic (full printable ASCII) password type.

Note that the back-quote character, "`" has been deliberately excluded from the symbol set for this type due to the risk of visual ambiguity between it and the more common single-quote "'" character.

See Also:
Constant Field Values

TYPE_MAX

public static final int TYPE_MAX
A convenience constant for use when range checking the type enumeration values.

A valid type value X must lie in the range 0 <= X <= MAXTYPE.

See Also:
Constant Field Values

LENGTH_MIN

public static final int LENGTH_MIN
This is the minimum possible password length which can be produced by this class. The reason for this limitation is in part due to the need to be able to satisfy the strict requirements when using multiple symbol sets. If ever a shorter password is required, the user should be instructed to use only the first portion of the generated password (and then complain to the web site concerned about their security).

See Also:
Constant Field Values

SALT_MAX

public static final int SALT_MAX
This is the upper limit on the acceptable size of the salt string. Because each character of the salt string available to an attacker reduces the search space for the private key by 6 bits, it is important not to have a very large salt string.

See Also:
Constant Field Values

BITS_PER_CHAR

public static final float[] BITS_PER_CHAR
Constructor Detail

GoSecure

public GoSecure(java.lang.String publicKey,
                java.lang.String privateKey,
                java.lang.String digest,
                int saltLength)
Initialise an instance of GoSecure using the given key and hashing scheme.

The requirement to provide separate public and private parts to the key is because the salt string must only be generated from the private part of any key. This is because the salt string is intended to be made public and is used to verify the correctness of the private part of any key.

Were we to use the entire key to generate the salt string then two different instances of this class which shared the same private key, but had different public keys, would yield different salt strings. An attacker who has access to multiple (public key, salt string) pairs would now have extra information with which to attack the private key.

Parameters:
publicKey - The public part of the key with which the password generator will be constructed. No reference to this string is kept by this class.
privateKey - The private part of the key with which the password generator will be constructed. No reference to this string is kept by this class.
digest - The name of the digest scheme to use for hashing the key string (for example "SHA-1"). See Appendix A in the Java Cryptography Architecture API Specification & Reference for information about standard algorithm names. Note however that not all these algorithms are guaranteed to be available on all Java implementations.
saltLength - The length of the salt string to be generated from the private key information. This value should be in the range (0 <= saltLength <= SALT_MAX) and a value of zero will result in getSalt() returning null (rather than the empty string). Each character of the salt string which is known to an attacker will reduce the search space for the private key by 6 bits, so if the salt string is used for verification purposes then the length of the private key should be increased to compensate.
Throws:
java.lang.IllegalArgumentException
Method Detail

getSalt

public final java.lang.String getSalt()
Returns the salt string constructed from the private key information. This can be used to verify a correctly entered passphrase later on. Note however the each character of the salt string which is made public reduces the search space for the passphrase by 6 bits.

Returns:
The salt string, a URL-safe base64 encoded string.

reset

public final void reset()
Resets the state of the password sequence to the same state as when this instance was first initialised.


getPassword

public final java.lang.String getPassword(int length,
                                          int type,
                                          int skip)
Get the next available password conforming to the given constraints.

Parameters:
length - The required length of the password (>=MINLENGTH)
type - The password type (0 <= X <= TYPE_MAX)
skip - The number of passwords which should be discarded before the final next is determined (non-negative). Using a non-zero value is useful if a previously calculated password for this service has been retired or when an initial password does not meet some externally defined requirements (such as having at least two numerals in it). Where the skip value needs to be made absolute with respect to the overall password sequence reset() should be called first.
Returns:
The next available password conforming to the given constraints.
Throws:
java.lang.IllegalArgumentException - If any of the arguments lie outside their stated ranges.