1 - Troublesome Scenario
Here's a simple scenario that illustrates why Random isn't ideal for secure applications: imagine if an application generated a session key using Random (predictable). If a hacker got their hands on a few sequential session keys from that insecure Random generator, with little work, they can predict the next session key in the sequence. This could then be used for a number of attacks, including hijacking a user session.
2 - My SecureRandomNumber Class (an example)
Here's my SecureRandomNumber class. It's available for use in your projects under the MIT License. This class also shows how to use Java's SecureRandom, if you don't want to directly use this code:
/**
* Copyright (c) 2009 Mark S. Kolich
* http://mark.koli.ch
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class SecureRandomNumber {
private static final String SHA1_PRNG = "SHA1PRNG";
// Default here is 64-bits of random goodness.
private static final int DEFAULT_RANDOM_SIZE = 64;
private static final char HEX_DIGIT [] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
// This isn't thread safe but we probably don't really care
// since all we're doing is reading a bunch of random numbers
// out of the generator.
private static final SecureRandom sRandom__;
static {
try {
sRandom__ = SecureRandom.getInstance( SHA1_PRNG );
} catch ( NoSuchAlgorithmException e ) {
throw new Error(e);
}
}
/**
* Get the number of next random bits in this SecureRandom
* generators' sequence.
* @param size how many random bits you want
* @return
* @throws IllegalArgumentException if the arg isn't divisible by eight
*/
public static byte [] getNextSecureRandom ( int bits ) {
// Make sure the number of bits we're asking for is at least
// divisible by 8.
if ( (bits % 8) != 0 ) {
throw new IllegalArgumentException("Size is not divisible " +
"by 8!");
}
// Usually 64-bits of randomness, 8 bytes
final byte [] bytes = new byte[ bits / 8 ];
// Get the next 64 random bits. Forces SecureRandom
// to seed itself before returning the bytes.
sRandom__.nextBytes(bytes);
return bytes;
}
/**
* Convert a byte array into its hex String
* equivalent.
* @param bytes
* @return
*/
public static String toHex ( byte [] bytes ) {
if ( bytes == null ) {
return null;
}
StringBuilder buffer = new StringBuilder(bytes.length*2);
for ( byte thisByte : bytes ) {
buffer.append(byteToHex(thisByte));
}
return buffer.toString();
}
/**
* Convert a single byte into its hex String
* equivalent.
* @param b
* @return
*/
private static String byteToHex ( byte b ) {
char [] array = { HEX_DIGIT[(b >> 4) & 0x0f],
HEX_DIGIT[b & 0x0f] };
return new String(array);
}
/**
* An example showing how to use SecureRandomNumber.
* @param args
*/
public static void main ( String [] args ) {
for ( int i = 0; i < 10; i++ ) {
// Get 64-bits of secure random goodness.
final byte [] randBytes =
SecureRandomNumber.
getNextSecureRandom(
DEFAULT_RANDOM_SIZE );
// Convert it to something pretty.
System.out.println(
SecureRandomNumber.toHex( randBytes ) );
}
}
}
Download SecureRandomNumber.java here.
Cheers.


Did you find this post helpful, or at least, interesting?