001: /*
002: * @(#)SecureRandom.java 1.43 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.security;
029:
030: import java.util.Enumeration;
031:
032: /**
033: * <p>This class provides a cryptographically strong pseudo-random number
034: * generator (PRNG). A cryptographically strong pseudo-random number
035: * minimally complies with the statistical random number generator tests
036: * specified in <a href="http://csrc.nist.gov/cryptval/140-2.htm"><i>FIPS 140-2, Security Requirements for Cryptographic Modules</i></a>, section 4.9.1.
037: * Additionally, SecureRandom must produce non-deterministic
038: * output and therefore it is required that the seed material be unpredictable
039: * and that output of SecureRandom be cryptographically strong sequences as
040: * described in <a href="http://www.ietf.org/rfc/rfc1750.txt"><i>RFC 1750: Randomness Recommendations for Security</i></a>.
041: *
042: * <p>Like other algorithm-based classes in Java Security, SecureRandom
043: * provides implementation-independent algorithms, whereby a caller
044: * (application code) requests a particular PRNG algorithm
045: * and is handed back a SecureRandom object for that algorithm. It is
046: * also possible, if desired, to request a particular algorithm from a
047: * particular provider. See the <code>getInstance</code> methods.
048: *
049: * <p>Thus, there are two ways to request a SecureRandom object: by
050: * specifying either just an algorithm name, or both an algorithm name
051: * and a package provider.
052: *
053: * <ul>
054: *
055: * <li>If just an algorithm name is specified, as in:
056: * <pre>
057: * SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
058: * </pre>
059: * the system will determine if there is an implementation of the algorithm
060: * requested available in the environment, and if there is more than one, if
061: * there is a preferred one.<p>
062: *
063: * <li>If both an algorithm name and a package provider are specified, as in:
064: * <pre>
065: * SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
066: * </pre>
067: * the system will determine if there is an implementation of the
068: * algorithm in the package requested, and throw an exception if there
069: * is not.
070: *
071: * </ul>
072: *
073: * <p>The SecureRandom implementation attempts to completely
074: * randomize the internal state of the generator itself unless
075: * the caller follows the call to a <code>getInstance</code> method
076: * with a call to the <code>setSeed</code> method:
077: * <pre>
078: * SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
079: * random.setSeed(seed);
080: * </pre>
081: *
082: * <p>After the caller obtains the SecureRandom object from the
083: * <code>getInstance</code> call, it can call <code>nextBytes</code>
084: * to generate random bytes:
085: * <pre>
086: * byte bytes[] = new byte[20];
087: * random.nextBytes(bytes);
088: * </pre>
089: *
090: * <p>The caller may also invoke the <code>generateSeed</code> method
091: * to generate a given number of seed bytes (to seed other random number
092: * generators, for example):
093: * <pre>
094: * byte seed[] = random.generateSeed(20);
095: * </pre>
096: *
097: * @see java.security.SecureRandomSpi
098: * @see java.util.Random
099: *
100: * @version 1.36, 02/02/00
101: * @author Benjamin Renaud
102: * @author Josh Bloch
103: */
104:
105: public class SecureRandom extends java.util.Random {
106:
107: /**
108: * The provider.
109: *
110: * @serial
111: * @since 1.2
112: */
113: private Provider provider = null;
114:
115: /**
116: * The provider implementation.
117: *
118: * @serial
119: * @since 1.2
120: */
121: private SecureRandomSpi secureRandomSpi = null;
122:
123: // Seed Generator
124: private static SecureRandom seedGenerator = null;
125:
126: /**
127: * <p>By using this constructor, the caller obtains a SecureRandom object
128: * containing the implementation from the highest-priority installed
129: * provider that has a SecureRandom implementation.
130: *
131: * <p>Note that this instance of SecureRandom has not been seeded.
132: * A call to the <code>setSeed</code> method will seed the SecureRandom
133: * object. If a call is not made to <code>setSeed</code>, the first call
134: * to the <code>nextBytes</code> method will force the SecureRandom object
135: * to seed itself.
136: *
137: * <p>This constructor is provided for backwards compatibility.
138: * The caller is encouraged to use one of the alternative
139: * <code>getInstance</code> methods to obtain a SecureRandom object.
140: */
141: public SecureRandom() {
142: /*
143: * This call to our superclass constructor will result in a call
144: * to our own <code>setSeed</code> method, which will return
145: * immediately when it is passed zero.
146: */
147: super (0);
148: String prng = getPrngAlgorithm();
149: if (prng == null) {
150: // bummer, get the SUN implementation
151: this .secureRandomSpi = new sun.security.provider.SecureRandom();
152: this .provider = new sun.security.provider.Sun();
153: } else {
154: try {
155: SecureRandom random = SecureRandom.getInstance(prng);
156: this .secureRandomSpi = random.getSecureRandomSpi();
157: this .provider = random.getProvider();
158: } catch (NoSuchAlgorithmException nsae) {
159: // never happens, because we made sure the algorithm exists
160: }
161: }
162: }
163:
164: /**
165: * <p>By using this constructor, the caller obtains a SecureRandom object
166: * containing the implementation from the highest-priority installed
167: * provider that has a SecureRandom implementation. This constructor
168: * uses a user-provided seed in
169: * preference to the self-seeding algorithm referred to in the empty
170: * constructor description. It may be preferable to the empty constructor
171: * if the caller has access to high-quality random bytes from some physical
172: * device (for example, a radiation detector or a noisy diode).
173: *
174: * <p>This constructor is provided for backwards compatibility.
175: * The caller is encouraged to use one of the alternative
176: * <code>getInstance</code> methods to obtain a SecureRandom object, and
177: * then to call the <code>setSeed</code> method to seed it.
178: *
179: * @param seed the seed.
180: */
181: public SecureRandom(byte seed[]) {
182: super (0);
183: String prng = getPrngAlgorithm();
184: if (prng == null) {
185: // bummer, get the SUN implementation
186: this .secureRandomSpi = new sun.security.provider.SecureRandom();
187: this .provider = new sun.security.provider.Sun();
188: this .secureRandomSpi.engineSetSeed(seed);
189: } else {
190: try {
191: SecureRandom random = getInstance(prng);
192: this .secureRandomSpi = random.getSecureRandomSpi();
193: this .provider = random.getProvider();
194: this .secureRandomSpi.engineSetSeed(seed);
195: } catch (NoSuchAlgorithmException nsae) {
196: // never happens, because we made sure the algorithm exists
197: }
198: }
199: }
200:
201: /**
202: * Creates a SecureRandom object.
203: *
204: * @param secureRandomSpi the SecureRandom implementation.
205: * @param provider the provider.
206: */
207: protected SecureRandom(SecureRandomSpi secureRandomSpi,
208: Provider provider) {
209: super (0);
210: this .secureRandomSpi = secureRandomSpi;
211: this .provider = provider;
212: }
213:
214: /**
215: * Generates a SecureRandom object that implements the specified
216: * Pseudo Random Number Generator (PRNG) algorithm. If the default
217: * provider package provides an implementation of the requested PRNG,
218: * an instance of SecureRandom containing that implementation is returned.
219: * If the PRNG is not available in the default
220: * package, other packages are searched.
221: *
222: * <p>Note that the returned instance of SecureRandom has not been seeded.
223: * A call to the <code>setSeed</code> method will seed the SecureRandom
224: * object. If a call is not made to <code>setSeed</code>, the first call
225: * to the <code>nextBytes</code> method will force the SecureRandom object
226: * to seed itself.
227: *
228: * @param algorithm the name of the PRNG algorithm.
229: * See Appendix A in the <a href=
230: * "../../../guide/security/CryptoSpec.html#AppA">
231: * Java Cryptography Architecture API Specification & Reference </a>
232: * for information about standard PRNG algorithm names.
233: *
234: * @return the new SecureRandom object.
235: *
236: * @exception NoSuchAlgorithmException if the PRNG algorithm is
237: * not available in the caller's environment.
238: *
239: * @since 1.2
240: */
241: public static SecureRandom getInstance(String algorithm)
242: throws NoSuchAlgorithmException {
243: try {
244: Object[] objs = Security.getImpl(algorithm, "SecureRandom",
245: (String) null);
246: return new SecureRandom((SecureRandomSpi) objs[0],
247: (Provider) objs[1]);
248: } catch (NoSuchProviderException e) {
249: throw new NoSuchAlgorithmException(algorithm + " not found");
250: }
251: }
252:
253: /**
254: * Generates a SecureRandom object for the specified PRNG
255: * algorithm, as supplied from the specified provider, if such a
256: * PRNG implementation is available from the provider.
257: *
258: * <p>Note that the returned instance of SecureRandom has not been seeded.
259: * A call to the <code>setSeed</code> method will seed the SecureRandom
260: * object. If a call is not made to <code>setSeed</code>, the first call
261: * to the <code>nextBytes</code> method will force the SecureRandom object
262: * to seed itself.
263: *
264: * @param algorithm the name of the PRNG algorithm.
265: * See Appendix A in the <a href=
266: * "../../../guide/security/CryptoSpec.html#AppA">
267: * Java Cryptography Architecture API Specification & Reference </a>
268: * for information about standard PRNG algorithm names.
269: *
270: * @param provider the name of the provider.
271: *
272: * @return the new SecureRandom object.
273: *
274: * @exception NoSuchAlgorithmException if the requested PRNG
275: * implementation is not available from the provider.
276: *
277: * @exception NoSuchProviderException if the provider has not been
278: * configured.
279: *
280: * @exception IllegalArgumentException if the provider name is null
281: * or empty.
282: *
283: * @see Provider
284: *
285: * @since 1.2
286: */
287: public static SecureRandom getInstance(String algorithm,
288: String provider) throws NoSuchAlgorithmException,
289: NoSuchProviderException {
290: if (provider == null || provider.length() == 0)
291: throw new IllegalArgumentException("missing provider");
292: Object[] objs = Security.getImpl(algorithm, "SecureRandom",
293: provider);
294: return new SecureRandom((SecureRandomSpi) objs[0],
295: (Provider) objs[1]);
296: }
297:
298: /**
299: * Generates a SecureRandom object for the specified PRNG
300: * algorithm, as supplied from the specified provider, if such a
301: * PRNG implementation is available from the provider.
302: * Note: the <code>provider</code> doesn't have to be registered.
303: *
304: * <p>Note that the returned instance of SecureRandom has not been seeded.
305: * A call to the <code>setSeed</code> method will seed the SecureRandom
306: * object. If a call is not made to <code>setSeed</code>, the first call
307: * to the <code>nextBytes</code> method will force the SecureRandom object
308: * to seed itself.
309: *
310: * @param algorithm the name of the PRNG algorithm.
311: * See Appendix A in the <a href=
312: * "../../../guide/security/CryptoSpec.html#AppA">
313: * Java Cryptography Architecture API Specification & Reference </a>
314: * for information about standard PRNG algorithm names.
315: *
316: * @param provider the provider.
317: *
318: * @return the new SecureRandom object.
319: *
320: * @exception NoSuchAlgorithmException if the requested PRNG
321: * implementation is not available from the provider.
322: *
323: * @exception IllegalArgumentException if the <code>provider</code> is
324: * null.
325: *
326: * @see Provider
327: *
328: * @since 1.4
329: */
330: public static SecureRandom getInstance(String algorithm,
331: Provider provider) throws NoSuchAlgorithmException {
332: if (provider == null)
333: throw new IllegalArgumentException("missing provider");
334: Object[] objs = Security.getImpl(algorithm, "SecureRandom",
335: provider);
336: return new SecureRandom((SecureRandomSpi) objs[0],
337: (Provider) objs[1]);
338: }
339:
340: /**
341: * Returns the SecureRandomSpi of this SecureRandom object.
342: */
343: SecureRandomSpi getSecureRandomSpi() {
344: return secureRandomSpi;
345: }
346:
347: /**
348: * Returns the provider of this SecureRandom object.
349: *
350: * @return the provider of this SecureRandom object.
351: */
352: public final Provider getProvider() {
353: return provider;
354: }
355:
356: /**
357: * Reseeds this random object. The given seed supplements, rather than
358: * replaces, the existing seed. Thus, repeated calls are guaranteed
359: * never to reduce randomness.
360: *
361: * @param seed the seed.
362: *
363: * @see #getSeed
364: */
365: synchronized public void setSeed(byte[] seed) {
366: secureRandomSpi.engineSetSeed(seed);
367: }
368:
369: /**
370: * Reseeds this random object, using the eight bytes contained
371: * in the given <code>long seed</code>. The given seed supplements,
372: * rather than replaces, the existing seed. Thus, repeated calls
373: * are guaranteed never to reduce randomness.
374: *
375: * <p>This method is defined for compatibility with
376: * <code>java.util.Random</code>.
377: *
378: * @param seed the seed.
379: *
380: * @see #getSeed
381: */
382: public void setSeed(long seed) {
383: /*
384: * Ignore call from super constructor (as well as any other calls
385: * unfortunate enough to be passing 0). It's critical that we
386: * ignore call from superclass constructor, as digest has not
387: * yet been initialized at that point.
388: */
389: if (seed != 0)
390: secureRandomSpi.engineSetSeed(longToByteArray(seed));
391: }
392:
393: /**
394: * Generates a user-specified number of random bytes. This method is
395: * used as the basis of all random entities returned by this class
396: * (except seed bytes).
397: *
398: * @param bytes the array to be filled in with random bytes.
399: */
400:
401: synchronized public void nextBytes(byte[] bytes) {
402: secureRandomSpi.engineNextBytes(bytes);
403: }
404:
405: /**
406: * Generates an integer containing the user-specified number of
407: * pseudo-random bits (right justified, with leading zeros). This
408: * method overrides a <code>java.util.Random</code> method, and serves
409: * to provide a source of random bits to all of the methods inherited
410: * from that class (for example, <code>nextInt</code>,
411: * <code>nextLong</code>, and <code>nextFloat</code>).
412: *
413: * @param numBits number of pseudo-random bits to be generated, where
414: * 0 <= <code>numBits</code> <= 32.
415: *
416: * @return an <code>int</code> containing the user-specified number
417: * of pseudo-random bits (right justified, with leading zeros).
418: */
419: final protected int next(int numBits) {
420: int numBytes = (numBits + 7) / 8;
421: byte b[] = new byte[numBytes];
422: int next = 0;
423:
424: nextBytes(b);
425: for (int i = 0; i < numBytes; i++)
426: next = (next << 8) + (b[i] & 0xFF);
427:
428: return next >>> (numBytes * 8 - numBits);
429: }
430:
431: /**
432: * Returns the given number of seed bytes, computed using the seed
433: * generation algorithm that this class uses to seed itself. This
434: * call may be used to seed other random number generators.
435: *
436: * <p>This method is only included for backwards compatibility.
437: * The caller is encouraged to use one of the alternative
438: * <code>getInstance</code> methods to obtain a SecureRandom object, and
439: * then call the <code>generateSeed</code> method to obtain seed bytes
440: * from that object.
441: *
442: * @param numBytes the number of seed bytes to generate.
443: *
444: * @return the seed bytes.
445: *
446: * @see #setSeed
447: */
448: public static byte[] getSeed(int numBytes) {
449: if (seedGenerator == null)
450: seedGenerator = new SecureRandom();
451: return seedGenerator.generateSeed(numBytes);
452: }
453:
454: /**
455: * Returns the given number of seed bytes, computed using the seed
456: * generation algorithm that this class uses to seed itself. This
457: * call may be used to seed other random number generators.
458: *
459: * @param numBytes the number of seed bytes to generate.
460: *
461: * @return the seed bytes.
462: */
463: public byte[] generateSeed(int numBytes) {
464: return secureRandomSpi.engineGenerateSeed(numBytes);
465: }
466:
467: /**
468: * Helper function to convert a long into a byte array (least significant
469: * byte first).
470: */
471: private static byte[] longToByteArray(long l) {
472: byte[] retVal = new byte[8];
473:
474: for (int i = 0; i < 8; i++) {
475: retVal[i] = (byte) l;
476: l >>= 8;
477: }
478:
479: return retVal;
480: }
481:
482: /**
483: * Gets a default PRNG algorithm by looking through all registered
484: * providers. Returns the first PRNG algorithm of the first provider that
485: * has registered a SecureRandom implementation, or null if none of the
486: * registered providers supplies a SecureRandom implementation.
487: */
488: private static String getPrngAlgorithm() {
489: Provider[] provs = Security.getProviders();
490: for (int i = 0; i < provs.length; i++) {
491: // search the provider's properties list for a property name
492: // that starts with "SecureRandom."
493: for (Enumeration e = provs[i].propertyNames(); e
494: .hasMoreElements();) {
495: String propName = (String) e.nextElement();
496: // if property name is followed by an atttribute, skip it
497: if ((propName.startsWith("SecureRandom."))
498: && (propName.indexOf(' ') < 0)) {
499: int index = propName.indexOf(".", 0);
500: return propName.substring(index + 1);
501: }
502: }
503: }
504: return null;
505: }
506:
507: // Declare serialVersionUID to be compatible with JDK1.1
508: static final long serialVersionUID = 4940670005562187L;
509:
510: // Retain unused values serialized from JDK1.1
511: /**
512: * @serial
513: */
514: private byte[] state;
515: /**
516: * @serial
517: */
518: private MessageDigest digest = null;
519: /**
520: * @serial
521: *
522: * We know that the MessageDigest class does not implement
523: * java.io.Serializable. However, since this field is no longer
524: * used, it will always be NULL and won't affect the serialization
525: * of the SecureRandom class itself.
526: */
527: private byte[] randomBytes;
528: /**
529: * @serial
530: */
531: private int randomBytesUsed;
532: /**
533: * @serial
534: */
535: private long counter;
536: }
|