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