[Webfunds-commits] java/webfunds/utils SecureRandomHack.java

Jeroen C. van Gelderen gelderen@cypherpunks.ai
Wed, 31 May 2000 20:31:19 -0400 (AST)


gelderen    00/05/31 20:31:19

  Added:       webfunds/utils SecureRandomHack.java
  Log:
  Initial version.

Revision  Changes    Path
1.1                  java/webfunds/utils/SecureRandomHack.java

Index: SecureRandomHack.java
===================================================================
/* $Id: SecureRandomHack.java,v 1.1 2000/06/01 00:31:19 gelderen Exp $
 *
 * Copyright (c) 2000 Systemics Inc. on behalf of
 * The WebFunds Development Team. All rights reserved.
 */
package webfunds.utils;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.SecureRandom;


/**
 * This class is a hack to speed up SecureRandom initialization, 
 * working around JDK 1.1 brain damage. 
 *
 * Just call it before you call your first SecureRandom() constructor.
 *
 * This will only improve speed on UN*X, Windows and Mac don't have 
 * a /dev/random nor something equivalent.
 *
 * @version $Revision: 1.1 $
 * @author Jeroen C. van Gelderen (gelderen@systemics.com)
 */
public final class SecureRandomHack
{
    /** Name of randomness device. */
    private static final File RANDOM_DEV = new File("/dev/random");


    /** Length of seed in bytes. */
    private static final int SEED_LEN = 20;


    /** Only static methods. */
    private SecureRandomHack() {}


    /** 
     * Initialize the SecureRandom PRNG as quickly as possible so that
     * future invocations of the SecureRandom ctor complete quickly.
     *
     * This method should be called before any SecureRandom ctor is
     * called and will block until a seed has been generated.
     */
    public static void initialize()
    {
        byte[] seed = getSeedFast();
        if( seed == null )
        {
            System.out.println("got it slow...");
            seed = getSeedSlow();
        }
        else
        {
            System.out.println("got it fast");
        }

        // Initialize PRNG and request some random bytes to
        // thwart lazy initialization on some JDKs.
        SecureRandom dummy = new SecureRandom(seed);
        dummy.nextBytes(seed);
    }


    /**
     * Obtain a seed quickly by reading from /dev/random.
     *
     * @return a 20-byte seed or null
     */
    private static byte[] getSeedFast()
    {
        try
        {
            FileInputStream fis = new FileInputStream(RANDOM_DEV);
            byte[] seed = new byte[SEED_LEN];
            int todo  = seed.length;
            int off   = 0;
            int count = 0;
            while( todo > 0 )
            {
                if( (count = fis.read(seed, off, todo)) == -1 )
                    throw new IOException("EOF");

                off  += count;
                todo -= count;
            }
            return seed;
        }
        catch(IOException e)
        {
            e.printStackTrace();
            System.out.println("Ignoring exception: " + e);
            return null;
        }
    }


    /**
     * Obtain a seed trough Sun's SecureRandom implementation which is very
     * slow and potentially not very secure. It's all Windows and Mac users
     * are gonna get however.
     *
     * @return 20-byte seed
     */
    private static byte[] getSeedSlow()
    {
        return SecureRandom.getSeed(SEED_LEN);
    }
}