1 /* SecureRandom.java --- Secure Random class implmentation
2 Copyright (C) 1999, 2001 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.security;
39 import java.io.Serializable;
40 import java.util.Random;
41 import java.util.Enumeration;
44 SecureRandom is the class interface for using SecureRandom
45 providers. It provides an interface to the SecureRandomSpi
46 engine so that programmers can generate pseudo-random numbers.
48 @author Mark Benvenuto <ivymccough@worldnet.att.net>
50 public class SecureRandom extends Random
53 long counter = 0; //Serialized
54 MessageDigest digest = null;
55 Provider provider = null;
56 byte[] randomBytes = null; //Always null
57 int randomBytesUsed = 0;
58 SecureRandomSpi secureRandomSpi = null;
62 Default constructor for SecureRandom. It constructs a
63 new SecureRandom by instantating the first SecureRandom
64 algorithm in the default security provier.
66 It is not seeded and should be seeded using setSeed or else
67 on the first call to getnextBytes it will force a seed.
69 It is maintained for backwards compatibility and programs
70 should use getInstance.
74 Provider p[] = Security.getProviders();
76 //Format of Key: SecureRandom.algname
79 String classname = null;
82 for (i = 0; i < p.length; i++)
84 e = p[i].propertyNames();
85 while (e.hasMoreElements())
87 key = (String) e.nextElement();
88 if (key.startsWith("SecureRandom."))
89 if ((classname = p[i].getProperty(key)) != null)
92 if (classname != null)
96 //if( classname == null)
97 // throw new NoSuchAlgorithmException();
101 this.secureRandomSpi =
102 (SecureRandomSpi) Class.forName(classname).newInstance();
104 //s.algorithm = algorithm;
105 this.provider = p[i];
107 catch (ClassNotFoundException cnfe)
109 //throw new NoSuchAlgorithmException("Class not found");
111 catch (InstantiationException ie)
113 //throw new NoSuchAlgorithmException("Class instantiation failed");
115 catch (IllegalAccessException iae)
117 //throw new NoSuchAlgorithmException("Illegal Access");
122 A constructor for SecureRandom. It constructs a new
123 SecureRandom by instantating the first SecureRandom algorithm
124 in the default security provier.
126 It is seeded with the passed function and is useful if the user
127 has access to hardware random device (like a radiation detector).
129 It is maintained for backwards compatibility and programs
130 should use getInstance.
132 @param seed Seed bytes for class
134 public SecureRandom(byte[] seed)
141 A constructor for SecureRandom. It constructs a new
142 SecureRandom using the specified SecureRandomSpi from
143 the specified security provier.
145 @param secureRandomSpi A SecureRandomSpi class
146 @param provider A Provider class
148 protected SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)
150 this.secureRandomSpi = secureRandomSpi;
151 this.provider = provider;
155 Returns an instance of a SecureRandom. It creates the class
156 for the specified algorithm if it exists from a provider.
158 @param algorithm A SecureRandom algorithm to use
160 @return Returns a new SecureRandom implmenting the chosen algorithm
162 @throws NoSuchAlgorithmException if the algorithm cannot be found
164 public static SecureRandom getInstance(String algorithm) throws
165 NoSuchAlgorithmException
167 Provider p[] = Security.getProviders();
169 //Format of Key: SecureRandom.algname
170 StringBuffer key = new StringBuffer("SecureRandom.");
171 key.append(algorithm);
173 String classname = null;
175 for (i = 0; i < p.length; i++)
177 if ((classname = p[i].getProperty(key.toString())) != null)
181 if (classname == null)
182 throw new NoSuchAlgorithmException();
186 return new SecureRandom((SecureRandomSpi) Class.forName(classname).
187 newInstance(), p[i]);
189 catch (ClassNotFoundException cnfe)
191 throw new NoSuchAlgorithmException("Class not found");
193 catch (InstantiationException ie)
195 throw new NoSuchAlgorithmException("Class instantiation failed");
197 catch (IllegalAccessException iae)
199 throw new NoSuchAlgorithmException("Illegal Access");
205 Returns an instance of a SecureRandom. It creates the class
206 for the specified algorithm from the specified provider.
208 @param algorithm A SecureRandom algorithm to use
209 @param provider A security provider to use
211 @return Returns a new SecureRandom implmenting the chosen algorithm
213 @throws NoSuchAlgorithmException if the algorithm cannot be found
214 @throws NoSuchProviderException if the provider cannot be found
216 public static SecureRandom getInstance(String algorithm,
217 String provider) throws
218 NoSuchAlgorithmException, NoSuchProviderException
220 Provider p = Security.getProvider(provider);
222 throw new NoSuchProviderException();
224 //Format of Key: SecureRandom.algName
225 StringBuffer key = new StringBuffer("SecureRandom.");
226 key.append(algorithm);
228 String classname = p.getProperty(key.toString());
229 if (classname == null)
230 throw new NoSuchAlgorithmException();
234 return new SecureRandom((SecureRandomSpi) Class.forName(classname).
237 catch (ClassNotFoundException cnfe)
239 throw new NoSuchAlgorithmException("Class not found");
241 catch (InstantiationException ie)
243 throw new NoSuchAlgorithmException("Class instantiation failed");
245 catch (IllegalAccessException iae)
247 throw new NoSuchAlgorithmException("Illegal Access");
253 Returns the provider being used by the current SecureRandom class.
255 @return The provider from which this SecureRandom was attained
257 public final Provider getProvider()
263 Seeds the SecureRandom. The class is re-seeded for each call and
264 each seed builds on the previous seed so as not to weaken security.
266 @param seed seed bytes to seed with
268 public void setSeed(byte[] seed)
270 secureRandomSpi.engineSetSeed(seed);
274 Seeds the SecureRandom. The class is re-seeded for each call and
275 each seed builds on the previous seed so as not to weaken security.
277 @param seed 8 seed bytes to seed with
279 public void setSeed(long seed)
281 // This particular setSeed will be called by Random.Random(), via
282 // our own constructor, before secureRandomSpi is initialized. In
283 // this case we can't call a method on secureRandomSpi, and we
284 // definitely don't want to throw a NullPointerException.
285 // Therefore we test.
286 if (secureRandomSpi != null)
288 byte tmp[] = { (byte) (0xff & (seed >> 56)),
289 (byte) (0xff & (seed >> 48)),
290 (byte) (0xff & (seed >> 40)),
291 (byte) (0xff & (seed >> 32)),
292 (byte) (0xff & (seed >> 24)),
293 (byte) (0xff & (seed >> 16)),
294 (byte) (0xff & (seed >> 8)),
297 secureRandomSpi.engineSetSeed(tmp);
302 Generates a user specified number of bytes. This function
303 is the basis for all the random functions.
305 @param bytes array to store generated bytes in
307 public void nextBytes(byte[] bytes)
309 randomBytesUsed += bytes.length;
311 secureRandomSpi.engineNextBytes(bytes);
315 Generates an integer containing the user specified
316 number of random bits. It is right justified and padded
319 @param numBits number of random bits to get, 0 <= numBits <= 32;
321 @return the random bits
323 protected final int next(int numBits)
328 byte tmp[] = new byte[numBits / 8 + (1 * (numBits % 8))];
330 secureRandomSpi.engineNextBytes(tmp);
331 randomBytesUsed += tmp.length;
336 for (int i = 0; i < tmp.length; i++)
337 ret |= tmp[i] << (8 * i);
343 Returns the given number of seed bytes. This method is
344 maintained only for backwards capability.
346 @param numBytes number of seed bytes to get
348 @return an array containing the seed bytes
350 public static byte[] getSeed(int numBytes)
352 byte tmp[] = new byte[numBytes];
354 new Random().nextBytes(tmp);
356 //return secureRandomSpi.engineGenerateSeed( numBytes );
360 Returns the specified number of seed bytes.
362 @param numBytes number of seed bytes to get
364 @return an array containing the seed bytes
366 public byte[] generateSeed(int numBytes)
368 return secureRandomSpi.engineGenerateSeed(numBytes);