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