27
28 import java.util.*;
29 import java.util.regex.*;
30
31 import java.security.Provider.Service;
32
33 import sun.security.jca.*;
34 import sun.security.jca.GetInstance.Instance;
35 import sun.security.util.Debug;
36
37 /**
38 * This class provides a cryptographically strong random number
39 * generator (RNG).
40 *
41 * <p>A cryptographically strong random number
42 * minimally complies with the statistical random number generator tests
43 * specified in
44 * <a href="http://csrc.nist.gov/publications/fips/fips140-2/fips1402.pdf">
45 * <i>FIPS 140-2, Security Requirements for Cryptographic Modules</i></a>,
46 * section 4.9.1.
47 * Additionally, SecureRandom must produce non-deterministic output.
48 * Therefore any seed material passed to a SecureRandom object must be
49 * unpredictable, and all SecureRandom output sequences must be
50 * cryptographically strong, as described in
51 * <a href="http://tools.ietf.org/html/rfc4086">
52 * <i>RFC 4086: Randomness Requirements for Security</i></a>.
53 *
54 * <p>A caller obtains a SecureRandom instance via the
55 * no-argument constructor or one of the {@code getInstance} methods:
56 *
57 * <pre>
58 * SecureRandom random = new SecureRandom();
59 * </pre>
60 *
61 * <p> Many SecureRandom implementations are in the form of a pseudo-random
62 * number generator (PRNG), which means they use a deterministic algorithm
63 * to produce a pseudo-random sequence from a true random seed.
64 * Other implementations may produce true random numbers,
65 * and yet others may use a combination of both techniques.
66 *
67 * <p> Typical callers of SecureRandom invoke the following methods
68 * to retrieve random bytes:
69 *
70 * <pre>
71 * SecureRandom random = new SecureRandom();
72 * byte[] bytes = new byte[20];
73 * random.nextBytes(bytes);
74 * </pre>
75 *
76 * <p> Callers may also invoke the {@code generateSeed} method
77 * to generate a given number of seed bytes (to seed other random number
78 * generators, for example):
79 * <pre>
80 * byte[] seed = random.generateSeed(20);
81 * </pre>
82 *
83 * Note: Depending on the implementation, the {@code generateSeed} and
84 * {@code nextBytes} methods may block as entropy is being gathered,
85 * for example, if they need to read from /dev/random on various Unix-like
86 * operating systems.
87 *
88 * @see java.security.SecureRandomSpi
89 * @see java.util.Random
90 *
91 * @author Benjamin Renaud
92 * @author Josh Bloch
93 */
94
95 public class SecureRandom extends java.util.Random {
96
97 private static final Debug pdebug =
98 Debug.getInstance("provider", "Provider");
99 private static final boolean skipDebug =
100 Debug.isOn("engine=") && !Debug.isOn("securerandom");
101
102 /**
103 * The provider.
104 *
105 * @serial
106 * @since 1.2
115 */
116 private SecureRandomSpi secureRandomSpi = null;
117
118 /*
119 * The algorithm name of null if unknown.
120 *
121 * @serial
122 * @since 1.5
123 */
124 private String algorithm;
125
126 // Seed Generator
127 private static volatile SecureRandom seedGenerator;
128
129 /**
130 * Constructs a secure random number generator (RNG) implementing the
131 * default random number algorithm.
132 *
133 * <p> This constructor traverses the list of registered security Providers,
134 * starting with the most preferred Provider.
135 * A new SecureRandom object encapsulating the
136 * SecureRandomSpi implementation from the first
137 * Provider that supports a SecureRandom (RNG) algorithm is returned.
138 * If none of the Providers support a RNG algorithm,
139 * then an implementation-specific default is returned.
140 *
141 * <p> Note that the list of registered providers may be retrieved via
142 * the {@link Security#getProviders() Security.getProviders()} method.
143 *
144 * <p> See the SecureRandom section in the <a href=
145 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
146 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
147 * for information about standard RNG algorithm names.
148 *
149 * <p> The returned SecureRandom object has not been seeded. To seed the
150 * returned object, call the {@code setSeed} method.
151 * If {@code setSeed} is not called, the first call to
152 * {@code nextBytes} will force the SecureRandom object to seed itself.
153 * This self-seeding will not occur if {@code setSeed} was
154 * previously called.
155 */
156 public SecureRandom() {
157 /*
158 * This call to our superclass constructor will result in a call
159 * to our own {@code setSeed} method, which will return
160 * immediately when it is passed zero.
161 */
162 super(0);
163 getDefaultPRNG(false, null);
164 }
165
166 /**
167 * Constructs a secure random number generator (RNG) implementing the
168 * default random number algorithm.
169 * The SecureRandom instance is seeded with the specified seed bytes.
170 *
171 * <p> This constructor traverses the list of registered security Providers,
172 * starting with the most preferred Provider.
173 * A new SecureRandom object encapsulating the
174 * SecureRandomSpi implementation from the first
175 * Provider that supports a SecureRandom (RNG) algorithm is returned.
176 * If none of the Providers support a RNG algorithm,
177 * then an implementation-specific default is returned.
178 *
179 * <p> Note that the list of registered providers may be retrieved via
180 * the {@link Security#getProviders() Security.getProviders()} method.
181 *
182 * <p> See the SecureRandom section in the <a href=
183 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
184 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
185 * for information about standard RNG algorithm names.
186 *
187 * @param seed the seed.
188 */
189 public SecureRandom(byte[] seed) {
190 super(0);
191 getDefaultPRNG(true, seed);
192 }
193
194 private void getDefaultPRNG(boolean setSeed, byte[] seed) {
195 String prng = getPrngAlgorithm();
196 if (prng == null) {
197 // bummer, get the SUN implementation
198 prng = "SHA1PRNG";
199 this.secureRandomSpi = new sun.security.provider.SecureRandom();
200 this.provider = Providers.getSunProvider();
201 if (setSeed) {
202 this.secureRandomSpi.engineSetSeed(seed);
203 }
204 } else {
205 try {
206 SecureRandom random = SecureRandom.getInstance(prng);
207 this.secureRandomSpi = random.getSecureRandomSpi();
208 this.provider = random.getProvider();
209 if (setSeed) {
210 this.secureRandomSpi.engineSetSeed(seed);
211 }
212 } catch (NoSuchAlgorithmException nsae) {
213 // never happens, because we made sure the algorithm exists
214 throw new RuntimeException(nsae);
215 }
216 }
217 // JDK 1.1 based implementations subclass SecureRandom instead of
218 // SecureRandomSpi. They will also go through this code path because
219 // they must call a SecureRandom constructor as it is their superclass.
220 // If we are dealing with such an implementation, do not set the
221 // algorithm value as it would be inaccurate.
222 if (getClass() == SecureRandom.class) {
223 this.algorithm = prng;
224 }
225 }
226
227 /**
228 * Creates a SecureRandom object.
229 *
230 * @param secureRandomSpi the SecureRandom implementation.
231 * @param provider the provider.
232 */
233 protected SecureRandom(SecureRandomSpi secureRandomSpi,
234 Provider provider) {
235 this(secureRandomSpi, provider, null);
236 }
237
238 private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider,
239 String algorithm) {
240 super(0);
241 this.secureRandomSpi = secureRandomSpi;
242 this.provider = provider;
243 this.algorithm = algorithm;
244
245 if (!skipDebug && pdebug != null) {
246 pdebug.println("SecureRandom." + algorithm +
247 " algorithm from: " + this.provider.getName());
248 }
249 }
250
251 /**
252 * Returns a SecureRandom object that implements the specified
253 * Random Number Generator (RNG) algorithm.
254 *
255 * <p> This method traverses the list of registered security Providers,
256 * starting with the most preferred Provider.
257 * A new SecureRandom object encapsulating the
258 * SecureRandomSpi implementation from the first
259 * Provider that supports the specified algorithm is returned.
260 *
261 * <p> Note that the list of registered providers may be retrieved via
262 * the {@link Security#getProviders() Security.getProviders()} method.
263 *
264 * <p> The returned SecureRandom object has not been seeded. To seed the
265 * returned object, call the {@code setSeed} method.
266 * If {@code setSeed} is not called, the first call to
267 * {@code nextBytes} will force the SecureRandom object to seed itself.
268 * This self-seeding will not occur if {@code setSeed} was
269 * previously called.
270 *
271 * @implNote
272 * The JDK Reference Implementation additionally uses the
273 * {@code jdk.security.provider.preferred} property to determine
274 * the preferred provider order for the specified algorithm. This
275 * may be different than the order of providers returned by
276 * {@link Security#getProviders() Security.getProviders()}.
277 *
278 * @param algorithm the name of the RNG algorithm.
279 * See the SecureRandom section in the <a href=
280 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
281 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
282 * for information about standard RNG algorithm names.
283 *
284 * @return the new SecureRandom object.
285 *
286 * @exception NoSuchAlgorithmException if no Provider supports a
287 * SecureRandomSpi implementation for the
288 * specified algorithm.
289 *
290 * @see Provider
291 *
292 * @since 1.2
293 */
294 public static SecureRandom getInstance(String algorithm)
295 throws NoSuchAlgorithmException {
296 Instance instance = GetInstance.getInstance("SecureRandom",
297 SecureRandomSpi.class, algorithm);
298 return new SecureRandom((SecureRandomSpi)instance.impl,
299 instance.provider, algorithm);
300 }
301
302 /**
303 * Returns a SecureRandom object that implements the specified
304 * Random Number Generator (RNG) algorithm.
305 *
306 * <p> A new SecureRandom object encapsulating the
307 * SecureRandomSpi implementation from the specified provider
308 * is returned. The specified provider must be registered
309 * in the security provider list.
310 *
311 * <p> Note that the list of registered providers may be retrieved via
312 * the {@link Security#getProviders() Security.getProviders()} method.
313 *
314 * <p> The returned SecureRandom object has not been seeded. To seed the
315 * returned object, call the {@code setSeed} method.
316 * If {@code setSeed} is not called, the first call to
317 * {@code nextBytes} will force the SecureRandom object to seed itself.
318 * This self-seeding will not occur if {@code setSeed} was
319 * previously called.
320 *
321 * @param algorithm the name of the RNG algorithm.
322 * See the SecureRandom section in the <a href=
323 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
324 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
325 * for information about standard RNG algorithm names.
326 *
327 * @param provider the name of the provider.
328 *
329 * @return the new SecureRandom object.
330 *
331 * @exception NoSuchAlgorithmException if a SecureRandomSpi
332 * implementation for the specified algorithm is not
333 * available from the specified provider.
334 *
335 * @exception NoSuchProviderException if the specified provider is not
336 * registered in the security provider list.
337 *
338 * @exception IllegalArgumentException if the provider name is null
339 * or empty.
340 *
341 * @see Provider
342 *
343 * @since 1.2
344 */
345 public static SecureRandom getInstance(String algorithm, String provider)
346 throws NoSuchAlgorithmException, NoSuchProviderException {
347 Instance instance = GetInstance.getInstance("SecureRandom",
348 SecureRandomSpi.class, algorithm, provider);
349 return new SecureRandom((SecureRandomSpi)instance.impl,
350 instance.provider, algorithm);
351 }
352
353 /**
354 * Returns a SecureRandom object that implements the specified
355 * Random Number Generator (RNG) algorithm.
356 *
357 * <p> A new SecureRandom object encapsulating the
358 * SecureRandomSpi implementation from the specified Provider
359 * object is returned. Note that the specified Provider object
360 * does not have to be registered in the provider list.
361 *
362 * <p> The returned SecureRandom object has not been seeded. To seed the
363 * returned object, call the {@code setSeed} method.
364 * If {@code setSeed} is not called, the first call to
365 * {@code nextBytes} will force the SecureRandom object to seed itself.
366 * This self-seeding will not occur if {@code setSeed} was
367 * previously called.
368 *
369 * @param algorithm the name of the RNG algorithm.
370 * See the SecureRandom section in the <a href=
371 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
372 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
373 * for information about standard RNG algorithm names.
374 *
375 * @param provider the provider.
376 *
377 * @return the new SecureRandom object.
378 *
379 * @exception NoSuchAlgorithmException if a SecureRandomSpi
380 * implementation for the specified algorithm is not available
381 * from the specified Provider object.
382 *
383 * @exception IllegalArgumentException if the specified provider is null.
384 *
385 * @see Provider
386 *
387 * @since 1.4
388 */
389 public static SecureRandom getInstance(String algorithm,
390 Provider provider) throws NoSuchAlgorithmException {
391 Instance instance = GetInstance.getInstance("SecureRandom",
392 SecureRandomSpi.class, algorithm, provider);
393 return new SecureRandom((SecureRandomSpi)instance.impl,
394 instance.provider, algorithm);
395 }
396
397 /**
398 * Returns the SecureRandomSpi of this SecureRandom object.
399 */
400 SecureRandomSpi getSecureRandomSpi() {
401 return secureRandomSpi;
402 }
403
404 /**
405 * Returns the provider of this SecureRandom object.
406 *
407 * @return the provider of this SecureRandom object.
408 */
409 public final Provider getProvider() {
410 return provider;
411 }
412
413 /**
414 * Returns the name of the algorithm implemented by this SecureRandom
415 * object.
416 *
417 * @return the name of the algorithm or {@code unknown}
418 * if the algorithm name cannot be determined.
419 * @since 1.5
420 */
421 public String getAlgorithm() {
422 return Objects.toString(algorithm, "unknown");
423 }
424
425 /**
426 * Reseeds this random object. The given seed supplements, rather than
427 * replaces, the existing seed. Thus, repeated calls are guaranteed
428 * never to reduce randomness.
429 *
430 * @param seed the seed.
431 *
432 * @see #getSeed
433 */
434 public synchronized void setSeed(byte[] seed) {
435 secureRandomSpi.engineSetSeed(seed);
436 }
437
438 /**
439 * Reseeds this random object, using the eight bytes contained
440 * in the given {@code long seed}. The given seed supplements,
441 * rather than replaces, the existing seed. Thus, repeated calls
442 * are guaranteed never to reduce randomness.
443 *
444 * <p>This method is defined for compatibility with
445 * {@code java.util.Random}.
446 *
447 * @param seed the seed.
448 *
449 * @see #getSeed
450 */
451 @Override
452 public void setSeed(long seed) {
453 /*
454 * Ignore call from super constructor (as well as any other calls
455 * unfortunate enough to be passing 0). It's critical that we
456 * ignore call from superclass constructor, as digest has not
457 * yet been initialized at that point.
458 */
459 if (seed != 0) {
460 secureRandomSpi.engineSetSeed(longToByteArray(seed));
461 }
462 }
463
464 /**
465 * Generates a user-specified number of random bytes.
466 *
467 * <p> If a call to {@code setSeed} had not occurred previously,
468 * the first call to this method forces this SecureRandom object
469 * to seed itself. This self-seeding will not occur if
470 * {@code setSeed} was previously called.
471 *
472 * @param bytes the array to be filled in with random bytes.
473 */
474 @Override
475 public void nextBytes(byte[] bytes) {
476 secureRandomSpi.engineNextBytes(bytes);
477 }
478
479 /**
480 * Generates an integer containing the user-specified number of
481 * pseudo-random bits (right justified, with leading zeros). This
482 * method overrides a {@code java.util.Random} method, and serves
483 * to provide a source of random bits to all of the methods inherited
484 * from that class (for example, {@code nextInt},
485 * {@code nextLong}, and {@code nextFloat}).
486 *
487 * @param numBits number of pseudo-random bits to be generated, where
488 * {@code 0 <= numBits <= 32}.
489 *
490 * @return an {@code int} containing the user-specified number
491 * of pseudo-random bits (right justified, with leading zeros).
492 */
493 @Override
494 protected final int next(int numBits) {
495 int numBytes = (numBits+7)/8;
496 byte[] b = new byte[numBytes];
497 int next = 0;
498
499 nextBytes(b);
500 for (int i = 0; i < numBytes; i++) {
501 next = (next << 8) + (b[i] & 0xFF);
502 }
503
504 return next >>> (numBytes*8 - numBits);
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 * <p>This method is only included for backwards compatibility.
513 * The caller is encouraged to use one of the alternative
514 * {@code getInstance} methods to obtain a SecureRandom object, and
515 * then call the {@code generateSeed} method to obtain seed bytes
516 * from that object.
517 *
518 * @param numBytes the number of seed bytes to generate.
519 *
520 * @return the seed bytes.
521 *
522 * @see #setSeed
523 */
524 public static byte[] getSeed(int numBytes) {
525 SecureRandom seedGen = seedGenerator;
526 if (seedGen == null) {
527 seedGen = new SecureRandom();
528 seedGenerator = seedGen;
529 }
530 return seedGen.generateSeed(numBytes);
531 }
532
533 /**
534 * Returns the given number of seed bytes, computed using the seed
535 * generation algorithm that this class uses to seed itself. This
536 * call may be used to seed other random number generators.
537 *
538 * @param numBytes the number of seed bytes to generate.
539 *
540 * @return the seed bytes.
541 */
542 public byte[] generateSeed(int numBytes) {
543 return secureRandomSpi.engineGenerateSeed(numBytes);
544 }
545
546 /**
547 * Helper function to convert a long into a byte array (least significant
548 * byte first).
549 */
550 private static byte[] longToByteArray(long l) {
551 byte[] retVal = new byte[8];
552
553 for (int i = 0; i < 8; i++) {
554 retVal[i] = (byte) l;
555 l >>= 8;
556 }
557
558 return retVal;
559 }
560
561 /**
562 * Gets a default PRNG algorithm by looking through all registered
563 * providers. Returns the first PRNG algorithm of the first provider that
564 * has registered a SecureRandom implementation, or null if none of the
565 * registered providers supplies a SecureRandom implementation.
566 */
567 private static String getPrngAlgorithm() {
568 for (Provider p : Providers.getProviderList().providers()) {
569 for (Service s : p.getServices()) {
570 if (s.getType().equals("SecureRandom")) {
571 return s.getAlgorithm();
572 }
573 }
574 }
575 return null;
576 }
577
578 /*
579 * Lazily initialize since Pattern.compile() is heavy.
580 * Effective Java (2nd Edition), Item 71.
581 */
582 private static final class StrongPatternHolder {
583 /*
584 * Entries are alg:prov separated by ,
585 * Allow for prepended/appended whitespace between entries.
649
650 try {
651 if (prov == null) {
652 return SecureRandom.getInstance(alg);
653 } else {
654 return SecureRandom.getInstance(alg, prov);
655 }
656 } catch (NoSuchAlgorithmException |
657 NoSuchProviderException e) {
658 }
659 remainder = m.group(5);
660 } else {
661 remainder = null;
662 }
663 }
664
665 throw new NoSuchAlgorithmException(
666 "No strong SecureRandom impls available: " + property);
667 }
668
669 // Declare serialVersionUID to be compatible with JDK1.1
670 static final long serialVersionUID = 4940670005562187L;
671
672 // Retain unused values serialized from JDK1.1
673 /**
674 * @serial
675 */
676 private byte[] state;
677 /**
678 * @serial
679 */
680 private MessageDigest digest = null;
681 /**
682 * @serial
683 *
684 * We know that the MessageDigest class does not implement
685 * java.io.Serializable. However, since this field is no longer
686 * used, it will always be NULL and won't affect the serialization
687 * of the SecureRandom class itself.
688 */
689 private byte[] randomBytes;
690 /**
691 * @serial
692 */
693 private int randomBytesUsed;
694 /**
695 * @serial
696 */
697 private long counter;
698 }
|
27
28 import java.util.*;
29 import java.util.regex.*;
30
31 import java.security.Provider.Service;
32
33 import sun.security.jca.*;
34 import sun.security.jca.GetInstance.Instance;
35 import sun.security.util.Debug;
36
37 /**
38 * This class provides a cryptographically strong random number
39 * generator (RNG).
40 *
41 * <p>A cryptographically strong random number
42 * minimally complies with the statistical random number generator tests
43 * specified in
44 * <a href="http://csrc.nist.gov/publications/fips/fips140-2/fips1402.pdf">
45 * <i>FIPS 140-2, Security Requirements for Cryptographic Modules</i></a>,
46 * section 4.9.1.
47 * Additionally, {@code SecureRandom} must produce non-deterministic output.
48 * Therefore any seed material passed to a {@code SecureRandom} object must be
49 * unpredictable, and all {@code SecureRandom} output sequences must be
50 * cryptographically strong, as described in
51 * <a href="http://tools.ietf.org/html/rfc4086">
52 * <i>RFC 4086: Randomness Requirements for Security</i></a>.
53 *
54 * <p> Many {@code SecureRandom} implementations are in the form of a pseudo-random
55 * number generator (PRNG, also known as deterministic random bits generator
56 * or DRBG), which means they use a deterministic algorithm
57 * to produce a pseudo-random sequence from a random seed.
58 * Other implementations may produce true random numbers,
59 * and yet others may use a combination of both techniques.
60 *
61 * <p>A caller obtains a {@code SecureRandom} instance via the
62 * no-argument constructor or one of the {@code getInstance} methods.
63 * For example:
64 *
65 * <blockquote><pre>
66 * SecureRandom r1 = new SecureRandom();
67 * SecureRandom r2 = SecureRandom.getInstance("NativePRNG");
68 * SecureRandom r3 = SecureRandom("DRBG",
69 * DrbgParameters.Instantiate(128, RESEED_ONLY, null));
70 * </pre></blockquote>
71 *
72 * <p> The third statement above returns a {@code SecureRandom} object of the
73 * specific algorithm supporting the specific instantiate parameters.
74 * The effective instantiate parameters used in the instantiation must match
75 * this minimum request but is not necessarily the same. For example,
76 * even if the request does not require a certain feature, the actual
77 * instantiation can provide the feature. An implementation may lazily
78 * instantiate a {@code SecureRandom} until it's actually used, but the effective
79 * instantiate parameters must be determined at the beginning and returned by
80 * {@link #getParameters()} unchanged.
81 *
82 * <p> Typical callers of {@code SecureRandom} invoke the following methods
83 * to retrieve random bytes:
84 *
85 * <blockquote><pre>
86 * SecureRandom random = new SecureRandom();
87 * byte[] bytes = new byte[20];
88 * random.nextBytes(bytes);
89 * </pre></blockquote>
90 *
91 * <p> Callers may also invoke the {@link #generateSeed} method
92 * to generate a given number of seed bytes (to seed other random number
93 * generators, for example):
94 *
95 * <blockquote><pre>
96 * byte[] seed = random.generateSeed(20);
97 * </pre></blockquote>
98 *
99 * <p> A newly created PRNG {@code SecureRandom} object is not seeded (except if
100 * it is created by {@link #SecureRandom(byte[])}). The first call to
101 * {@code nextBytes} will force it to seed itself from an implementation-
102 * specific entropy source. This self-seeding will not occur if {@code setSeed}
103 * was previously called.
104 *
105 * <p> A {@code SecureRandom} can be reseeded at any time by calling the
106 * {@code reseed} or {@code setSeed} method. The {@code reseed} method
107 * reads entropy input from its entropy source to reseed itself.
108 * The {@code setSeed} method requires the caller to provide the seed.
109 *
110 * <p> Please note that {@code reseed} is not always supported.
111 *
112 * <p> Some {@code SecureRandom} implementations may accept a
113 * {@link SecureRandomNextBytesParameters} parameter in its
114 * {@link #nextBytes(byte[], SecureRandomNextBytesParameters)} method and a
115 * {@link SecureRandomReseedParameters} in its
116 * {@link #reseed(SecureRandomReseedParameters)} method to further
117 * control the behavior of the methods.
118 *
119 * <p> Note: Depending on the implementation, the {@code generateSeed},
120 * {@code reseed} and {@code nextBytes} methods may block as entropy is being
121 * gathered, for example, if the entropy source is /dev/random on various
122 * Unix-like operating systems.
123 *
124 * @see java.security.SecureRandomSpi
125 * @see java.util.Random
126 *
127 * @author Benjamin Renaud
128 * @author Josh Bloch
129 */
130
131 public class SecureRandom extends java.util.Random {
132
133 private static final Debug pdebug =
134 Debug.getInstance("provider", "Provider");
135 private static final boolean skipDebug =
136 Debug.isOn("engine=") && !Debug.isOn("securerandom");
137
138 /**
139 * The provider.
140 *
141 * @serial
142 * @since 1.2
151 */
152 private SecureRandomSpi secureRandomSpi = null;
153
154 /*
155 * The algorithm name of null if unknown.
156 *
157 * @serial
158 * @since 1.5
159 */
160 private String algorithm;
161
162 // Seed Generator
163 private static volatile SecureRandom seedGenerator;
164
165 /**
166 * Constructs a secure random number generator (RNG) implementing the
167 * default random number algorithm.
168 *
169 * <p> This constructor traverses the list of registered security Providers,
170 * starting with the most preferred Provider.
171 * A new {@code SecureRandom} object encapsulating the
172 * {@code SecureRandomSpi} implementation from the first
173 * Provider that supports a {@code SecureRandom} (RNG) algorithm is returned.
174 * If none of the Providers support a RNG algorithm,
175 * then an implementation-specific default is returned.
176 *
177 * <p> Note that the list of registered providers may be retrieved via
178 * the {@link Security#getProviders() Security.getProviders()} method.
179 *
180 * <p> See the {@code SecureRandom} section in the <a href=
181 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
182 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
183 * for information about standard RNG algorithm names.
184 */
185 public SecureRandom() {
186 /*
187 * This call to our superclass constructor will result in a call
188 * to our own {@code setSeed} method, which will return
189 * immediately when it is passed zero.
190 */
191 super(0);
192 getDefaultPRNG(false, null);
193 }
194
195 /**
196 * Constructs a secure random number generator (RNG) implementing the
197 * default random number algorithm.
198 * The {@code SecureRandom} instance is seeded with the specified seed bytes.
199 *
200 * <p> This constructor traverses the list of registered security Providers,
201 * starting with the most preferred Provider.
202 * A new {@code SecureRandom} object encapsulating the
203 * {@code SecureRandomSpi} implementation from the first
204 * Provider that supports a {@code SecureRandom} (RNG) algorithm is returned.
205 * If none of the Providers support a RNG algorithm,
206 * then an implementation-specific default is returned.
207 *
208 * <p> Note that the list of registered providers may be retrieved via
209 * the {@link Security#getProviders() Security.getProviders()} method.
210 *
211 * <p> See the {@code SecureRandom} section in the <a href=
212 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
213 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
214 * for information about standard RNG algorithm names.
215 *
216 * @param seed the seed.
217 */
218 public SecureRandom(byte[] seed) {
219 super(0);
220 getDefaultPRNG(true, seed);
221 }
222
223 private void getDefaultPRNG(boolean setSeed, byte[] seed) {
224 String prng = getPrngAlgorithm();
225 if (prng == null) {
226 // bummer, get the SUN implementation
227 prng = "SHA1PRNG";
228 this.secureRandomSpi = new sun.security.provider.SecureRandom();
229 this.provider = Providers.getSunProvider();
230 if (setSeed) {
231 this.setSeed(seed);
232 }
233 } else {
234 try {
235 SecureRandom random = SecureRandom.getInstance(prng);
236 this.secureRandomSpi = random.getSecureRandomSpi();
237 this.provider = random.getProvider();
238 if (setSeed) {
239 this.setSeed(seed);
240 }
241 } catch (NoSuchAlgorithmException nsae) {
242 // never happens, because we made sure the algorithm exists
243 throw new RuntimeException(nsae);
244 }
245 }
246 // JDK 1.1 based implementations subclass SecureRandom instead of
247 // SecureRandomSpi. They will also go through this code path because
248 // they must call a SecureRandom constructor as it is their superclass.
249 // If we are dealing with such an implementation, do not set the
250 // algorithm value as it would be inaccurate.
251 if (getClass() == SecureRandom.class) {
252 this.algorithm = prng;
253 }
254 }
255
256 /**
257 * Creates a {@code SecureRandom} object.
258 *
259 * @param secureRandomSpi the {@code SecureRandom} implementation.
260 * @param provider the provider.
261 */
262 protected SecureRandom(SecureRandomSpi secureRandomSpi,
263 Provider provider) {
264 this(secureRandomSpi, provider, null);
265 }
266
267 private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider,
268 String algorithm) {
269 super(0);
270 this.secureRandomSpi = secureRandomSpi;
271 this.provider = provider;
272 this.algorithm = algorithm;
273
274 if (!skipDebug && pdebug != null) {
275 pdebug.println("SecureRandom." + algorithm +
276 " algorithm from: " + this.provider.getName());
277 }
278 }
279
280 /**
281 * Returns a {@code SecureRandom} object that implements the specified
282 * Random Number Generator (RNG) algorithm.
283 *
284 * <p> This method traverses the list of registered security Providers,
285 * starting with the most preferred Provider.
286 * A new {@code SecureRandom} object encapsulating the
287 * {@code SecureRandomSpi} implementation from the first
288 * Provider that supports the specified algorithm is returned.
289 *
290 * <p> Note that the list of registered providers may be retrieved via
291 * the {@link Security#getProviders() Security.getProviders()} method.
292 *
293 * @implNote
294 * The JDK Reference Implementation additionally uses the
295 * {@code jdk.security.provider.preferred} property to determine
296 * the preferred provider order for the specified algorithm. This
297 * may be different than the order of providers returned by
298 * {@link Security#getProviders() Security.getProviders()}.
299 *
300 * @param algorithm the name of the RNG algorithm.
301 * See the {@code SecureRandom} section in the <a href=
302 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
303 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
304 * for information about standard RNG algorithm names.
305 *
306 * @return the new {@code SecureRandom} object.
307 *
308 * @exception NoSuchAlgorithmException if no Provider supports a
309 * {@code SecureRandomSpi} implementation for the
310 * specified algorithm.
311 *
312 * @see Provider
313 *
314 * @since 1.2
315 */
316 public static SecureRandom getInstance(String algorithm)
317 throws NoSuchAlgorithmException {
318 Instance instance = GetInstance.getInstance("SecureRandom",
319 SecureRandomSpi.class, algorithm);
320 return new SecureRandom((SecureRandomSpi)instance.impl,
321 instance.provider, algorithm);
322 }
323
324 /**
325 * Returns a {@code SecureRandom} object that implements the specified
326 * Random Number Generator (RNG) algorithm.
327 *
328 * <p> A new {@code SecureRandom} object encapsulating the
329 * {@code SecureRandomSpi} implementation from the specified provider
330 * is returned. The specified provider must be registered
331 * in the security provider list.
332 *
333 * <p> Note that the list of registered providers may be retrieved via
334 * the {@link Security#getProviders() Security.getProviders()} method.
335 *
336 * @param algorithm the name of the RNG algorithm.
337 * See the {@code SecureRandom} section in the <a href=
338 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
339 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
340 * for information about standard RNG algorithm names.
341 *
342 * @param provider the name of the provider.
343 *
344 * @return the new {@code SecureRandom} object.
345 *
346 * @throws NoSuchAlgorithmException if a {@code SecureRandomSpi}
347 * implementation for the specified algorithm is not
348 * available from the specified provider.
349 *
350 * @throws NoSuchProviderException if the specified provider is not
351 * registered in the security provider list.
352 *
353 * @throws IllegalArgumentException if the provider name is null
354 * or empty.
355 *
356 * @see Provider
357 *
358 * @since 1.2
359 */
360 public static SecureRandom getInstance(String algorithm, String provider)
361 throws NoSuchAlgorithmException, NoSuchProviderException {
362 Instance instance = GetInstance.getInstance("SecureRandom",
363 SecureRandomSpi.class, algorithm, provider);
364 return new SecureRandom((SecureRandomSpi)instance.impl,
365 instance.provider, algorithm);
366 }
367
368 /**
369 * Returns a {@code SecureRandom} object that implements the specified
370 * Random Number Generator (RNG) algorithm.
371 *
372 * <p> A new {@code SecureRandom} object encapsulating the
373 * {@code SecureRandomSpi} implementation from the specified {@code Provider}
374 * object is returned. Note that the specified {@code Provider} object
375 * does not have to be registered in the provider list.
376 *
377 * @param algorithm the name of the RNG algorithm.
378 * See the {@code SecureRandom} section in the <a href=
379 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
380 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
381 * for information about standard RNG algorithm names.
382 *
383 * @param provider the provider.
384 *
385 * @return the new {@code SecureRandom} object.
386 *
387 * @throws NoSuchAlgorithmException if a {@code SecureRandomSpi}
388 * implementation for the specified algorithm is not available
389 * from the specified {@code Provider} object.
390 *
391 * @throws IllegalArgumentException if the specified provider is null.
392 *
393 * @see Provider
394 *
395 * @since 1.4
396 */
397 public static SecureRandom getInstance(String algorithm,
398 Provider provider) throws NoSuchAlgorithmException {
399 Instance instance = GetInstance.getInstance("SecureRandom",
400 SecureRandomSpi.class, algorithm, provider);
401 return new SecureRandom((SecureRandomSpi)instance.impl,
402 instance.provider, algorithm);
403 }
404
405 /**
406 * Returns a {@code SecureRandom} object that implements the specified Random
407 * Number Generator (RNG) algorithm and supports the specified
408 * {@code SecureRandomInstantiateParameters} request.
409 *
410 * <p> This method traverses the list of registered security Providers,
411 * starting with the most preferred Provider.
412 * A new {@code SecureRandom} object encapsulating the
413 * {@code SecureRandomSpi} implementation from the first
414 * Provider that supports the specified algorithm and the specified
415 * {@code SecureRandomInstantiateParameters} is returned.
416 *
417 * <p> Note that the list of registered providers may be retrieved via
418 * the {@link Security#getProviders() Security.getProviders()} method.
419 *
420 * @implNote
421 * The JDK Reference Implementation additionally uses the
422 * {@code jdk.security.provider.preferred} property to determine
423 * the preferred provider order for the specified algorithm. This
424 * may be different than the order of providers returned by
425 * {@link Security#getProviders() Security.getProviders()}.
426 *
427 * @param algorithm the name of the RNG algorithm.
428 * See the {@code SecureRandom} section in the <a href=
429 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
430 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
431 * for information about standard RNG algorithm names.
432 *
433 * @param params the {@code SecureRandomInstantiateParameters}
434 * the newly created {@code SecureRandom} object must support.
435 *
436 * @return the new {@code SecureRandom} object.
437 *
438 * @throws NoSuchAlgorithmException if no Provider supports a
439 * {@code SecureRandomSpi} implementation for the specified algorithm
440 * and parameters.
441 *
442 * @throws IllegalArgumentException if the specified params is null.
443 *
444 * @see Provider
445 *
446 * @since 9
447 */
448 public static SecureRandom getInstance(
449 String algorithm, SecureRandomInstantiateParameters params)
450 throws NoSuchAlgorithmException {
451 if (params == null) {
452 throw new IllegalArgumentException("params cannot be null");
453 }
454 Instance instance = GetInstance.getInstance("SecureRandom",
455 SecureRandomSpi.class, algorithm, params);
456 SecureRandomSpi spi = (SecureRandomSpi) instance.impl;
457 SecureRandom r = new SecureRandom(spi, instance.provider, algorithm);
458 return r;
459 }
460
461 /**
462 * Returns a {@code SecureRandom} object that implements the specified Random
463 * Number Generator (RNG) algorithm and supports the specified
464 * {@code SecureRandomInstantiateParameters} request.
465 *
466 * <p> A new {@code SecureRandom} object encapsulating the
467 * {@code SecureRandomSpi} implementation from the specified provider
468 * is returned. The specified provider must be registered
469 * in the security provider list.
470 *
471 * <p> Note that the list of registered providers may be retrieved via
472 * the {@link Security#getProviders() Security.getProviders()} method.
473 *
474 * @param algorithm the name of the RNG algorithm.
475 * See the {@code SecureRandom} section in the <a href=
476 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
477 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
478 * for information about standard RNG algorithm names.
479 *
480 * @param params the {@code SecureRandomInstantiateParameters}
481 * the newly created {@code SecureRandom} object must support.
482 *
483 * @param provider the name of the provider.
484 *
485 * @return the new {@code SecureRandom} object.
486 *
487 * @throws NoSuchAlgorithmException if the specified provider does not
488 * support a {@code SecureRandomSpi} implementation for the specified
489 * algorithm and parameters.
490 *
491 * @throws NoSuchProviderException if the specified provider is not
492 * registered in the security provider list.
493 *
494 * @throws IllegalArgumentException if the provider name is null
495 * or empty, or params is null.
496 *
497 * @see Provider
498 *
499 * @since 9
500 */
501 public static SecureRandom getInstance(String algorithm,
502 SecureRandomInstantiateParameters params, String provider)
503 throws NoSuchAlgorithmException, NoSuchProviderException {
504 if (params == null) {
505 throw new IllegalArgumentException("params cannot be null");
506 }
507 Instance instance = GetInstance.getInstance("SecureRandom",
508 SecureRandomSpi.class, algorithm, params, provider);
509 SecureRandomSpi spi = (SecureRandomSpi)instance.impl;
510 return new SecureRandom(spi, instance.provider, algorithm);
511 }
512
513 /**
514 * Returns a {@code SecureRandom} object that implements the specified Random
515 * Number Generator (RNG) algorithm and supports the specified
516 * {@code SecureRandomInstantiateParameters} request.
517 *
518 * <p> A new {@code SecureRandom} object encapsulating the
519 * {@code SecureRandomSpi} implementation from the specified {@code Provider}
520 * object is returned. Note that the specified {@code Provider} object
521 * does not have to be registered in the provider list.
522 *
523 * @param algorithm the name of the RNG algorithm.
524 * See the {@code SecureRandom} section in the <a href=
525 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
526 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
527 * for information about standard RNG algorithm names.
528 *
529 * @param params the {@code SecureRandomInstantiateParameters}
530 * the newly created {@code SecureRandom} object must support.
531 *
532 * @param provider the provider.
533 *
534 * @return the new {@code SecureRandom} object.
535 *
536 * @throws NoSuchAlgorithmException if the specified provider does not
537 * support a {@code SecureRandomSpi} implementation for the specified
538 * algorithm and parameters.
539 *
540 * @throws IllegalArgumentException if the specified provider or params
541 * is null.
542 *
543 * @see Provider
544 *
545 * @since 9
546 */
547 public static SecureRandom getInstance(String algorithm,
548 SecureRandomInstantiateParameters params, Provider provider)
549 throws NoSuchAlgorithmException {
550 if (params == null) {
551 throw new IllegalArgumentException("params cannot be null");
552 }
553 Instance instance = GetInstance.getInstance("SecureRandom",
554 SecureRandomSpi.class, algorithm, params, provider);
555 SecureRandomSpi spi = (SecureRandomSpi)instance.impl;
556 return new SecureRandom(spi, instance.provider, algorithm);
557 }
558
559 /**
560 * Returns the {@code SecureRandomSpi} of this {@code SecureRandom} object.
561 */
562 SecureRandomSpi getSecureRandomSpi() {
563 return secureRandomSpi;
564 }
565
566 /**
567 * Returns the provider of this {@code SecureRandom} object.
568 *
569 * @return the provider of this {@code SecureRandom} object.
570 */
571 public final Provider getProvider() {
572 return provider;
573 }
574
575 /**
576 * Returns the name of the algorithm implemented by this {@code SecureRandom}
577 * object.
578 *
579 * @return the name of the algorithm or {@code unknown}
580 * if the algorithm name cannot be determined.
581 * @since 1.5
582 */
583 public String getAlgorithm() {
584 return Objects.toString(algorithm, "unknown");
585 }
586
587 @Override
588 public String toString() {
589 return secureRandomSpi.toString();
590 }
591
592 /**
593 * Returns the effective {@link SecureRandomInstantiateParameters} that
594 * is actually used to instantiate this {@code SecureRandom}.
595 * <p>
596 * The returned value can be different from the
597 * {@code SecureRandomInstantiateParameters} object passed into
598 * a {@code getInstance} method, but it cannot change during the lifetime
599 * of this {@code SecureRandom} object.
600 * <p>
601 * A caller can use the returned value to find out what features this
602 * {@code SecureRandom} supports.
603 *
604 * @return the parameters used in instantiation, or {@code null} if no
605 * parameters were used.
606 *
607 * @since 9
608 * @see SecureRandomSpi
609 */
610 public SecureRandomInstantiateParameters getParameters() {
611 return secureRandomSpi.engineGetParameters();
612 }
613
614 /**
615 * Reseeds this random object with the given seed. The seed supplements,
616 * rather than replaces, the existing seed. Thus, repeated calls are
617 * guaranteed never to reduce randomness.
618 * <p>
619 * A PRNG {@code SecureRandom} will not seed itself automatically if {@code setSeed}
620 * is called before any {@code nextBytes} or {@code reseed} calls.
621 * The caller should make sure that the {@code seed} argument contains
622 * enough entropy for the security of this {@code SecureRandom}.
623 *
624 * @param seed the seed.
625 *
626 * @see #getSeed
627 */
628 public synchronized void setSeed(byte[] seed) {
629 secureRandomSpi.engineSetSeed(seed);
630 }
631
632 /**
633 * Reseeds this random object, using the eight bytes contained
634 * in the given {@code long seed}. The given seed supplements,
635 * rather than replaces, the existing seed. Thus, repeated calls
636 * are guaranteed never to reduce randomness.
637 *
638 * <p>This method is defined for compatibility with
639 * {@code java.util.Random}.
640 *
641 * @param seed the seed.
642 *
643 * @see #getSeed
644 */
645 @Override
646 public void setSeed(long seed) {
647 /*
648 * Ignore call from super constructor (as well as any other calls
649 * unfortunate enough to be passing 0). It's critical that we
650 * ignore call from superclass constructor, as digest has not
651 * yet been initialized at that point.
652 */
653 if (seed != 0) {
654 setSeed(longToByteArray(seed));
655 }
656 }
657
658 /**
659 * Generates a user-specified number of random bytes.
660 *
661 * @param bytes the array to be filled in with random bytes.
662 *
663 * @throws NullPointerException if {@code bytes} is null.
664 */
665 @Override
666 public void nextBytes(byte[] bytes) {
667 secureRandomSpi.engineNextBytes(
668 Objects.requireNonNull(bytes));
669 }
670
671 /**
672 * Generates a user-specified number of random bytes with
673 * additional parameters.
674 *
675 * @param bytes the array to be filled in with random bytes
676 * @param params additional parameters
677 * @throws NullPointerException if {@code bytes} is null
678 * @throws UnsupportedOperationException if the underlying provider
679 * implementation has not overridden this method.
680 * @throws IllegalArgumentException if {@code params} is {@code null},
681 * unrecognizable or unsupported by this {@code SecureRandom}
682 *
683 * @since 9
684 */
685 public synchronized void nextBytes(
686 byte[] bytes, SecureRandomNextBytesParameters params) {
687 if (params == null) {
688 throw new IllegalArgumentException("params cannot be null");
689 }
690 secureRandomSpi.engineNextBytes(Objects.requireNonNull(bytes), params);
691 }
692
693 /**
694 * Generates an integer containing the user-specified number of
695 * pseudo-random bits (right justified, with leading zeros). This
696 * method overrides a {@code java.util.Random} method, and serves
697 * to provide a source of random bits to all of the methods inherited
698 * from that class (for example, {@code nextInt},
699 * {@code nextLong}, and {@code nextFloat}).
700 *
701 * @param numBits number of pseudo-random bits to be generated, where
702 * {@code 0 <= numBits <= 32}.
703 *
704 * @return an {@code int} containing the user-specified number
705 * of pseudo-random bits (right justified, with leading zeros).
706 */
707 @Override
708 protected final int next(int numBits) {
709 int numBytes = (numBits+7)/8;
710 byte[] b = new byte[numBytes];
711 int next = 0;
712
713 nextBytes(b);
714 for (int i = 0; i < numBytes; i++) {
715 next = (next << 8) + (b[i] & 0xFF);
716 }
717
718 return next >>> (numBytes*8 - numBits);
719 }
720
721 /**
722 * Returns the given number of seed bytes, computed using the seed
723 * generation algorithm that this class uses to seed itself. This
724 * call may be used to seed other random number generators.
725 *
726 * <p>This method is only included for backwards compatibility.
727 * The caller is encouraged to use one of the alternative
728 * {@code getInstance} methods to obtain a {@code SecureRandom} object, and
729 * then call the {@code generateSeed} method to obtain seed bytes
730 * from that object.
731 *
732 * @param numBytes the number of seed bytes to generate.
733 *
734 * @return the seed bytes.
735 *
736 * @see #setSeed
737 */
738 public static byte[] getSeed(int numBytes) {
739 SecureRandom seedGen = seedGenerator;
740 if (seedGen == null) {
741 seedGen = new SecureRandom();
742 seedGenerator = seedGen;
743 }
744 return seedGen.generateSeed(numBytes);
745 }
746
747 /**
748 * Returns the given number of seed bytes, computed using the seed
749 * generation algorithm that this class uses to seed itself. This
750 * call may be used to seed other random number generators.
751 *
752 * @param numBytes the number of seed bytes to generate.
753 * @throws IllegalArgumentException if {@code numBytes} is negative
754 * @return the seed bytes.
755 */
756 public byte[] generateSeed(int numBytes) {
757 if (numBytes < 0) {
758 throw new IllegalArgumentException("numBytes cannot be negative");
759 }
760 return secureRandomSpi.engineGenerateSeed(numBytes);
761 }
762
763 /**
764 * Helper function to convert a long into a byte array (least significant
765 * byte first).
766 */
767 private static byte[] longToByteArray(long l) {
768 byte[] retVal = new byte[8];
769
770 for (int i = 0; i < 8; i++) {
771 retVal[i] = (byte) l;
772 l >>= 8;
773 }
774
775 return retVal;
776 }
777
778 /**
779 * Gets a default PRNG algorithm by looking through all registered
780 * providers. Returns the first PRNG algorithm of the first provider that
781 * has registered a {@code SecureRandom} implementation, or null if none of the
782 * registered providers supplies a {@code SecureRandom} implementation.
783 */
784 private static String getPrngAlgorithm() {
785 for (Provider p : Providers.getProviderList().providers()) {
786 for (Service s : p.getServices()) {
787 if (s.getType().equals("SecureRandom")) {
788 return s.getAlgorithm();
789 }
790 }
791 }
792 return null;
793 }
794
795 /*
796 * Lazily initialize since Pattern.compile() is heavy.
797 * Effective Java (2nd Edition), Item 71.
798 */
799 private static final class StrongPatternHolder {
800 /*
801 * Entries are alg:prov separated by ,
802 * Allow for prepended/appended whitespace between entries.
866
867 try {
868 if (prov == null) {
869 return SecureRandom.getInstance(alg);
870 } else {
871 return SecureRandom.getInstance(alg, prov);
872 }
873 } catch (NoSuchAlgorithmException |
874 NoSuchProviderException e) {
875 }
876 remainder = m.group(5);
877 } else {
878 remainder = null;
879 }
880 }
881
882 throw new NoSuchAlgorithmException(
883 "No strong SecureRandom impls available: " + property);
884 }
885
886 /**
887 * Reseeds this {@code SecureRandom} with entropy input read from its
888 * entropy source.
889 *
890 * @throws UnsupportedOperationException if the underlying provider
891 * implementation has not overridden this method.
892 *
893 * @since 9
894 */
895 public synchronized void reseed() {
896 secureRandomSpi.engineReseed(null);
897 }
898
899 /**
900 * Reseeds this {@code SecureRandom} with entropy input read from its
901 * entropy source with additional parameters.
902 * <p>
903 * Note that entropy is obtained from an entropy source. While
904 * some data in {@code params} may contain entropy, its main usage is to
905 * provide diversity.
906 *
907 * @param params extra parameters
908 * @throws UnsupportedOperationException if the underlying provider
909 * implementation has not overridden this method.
910 * @throws IllegalArgumentException if {@code params} is {@code null},
911 * unrecognizable or unsupported by this {@code SecureRandom}
912 *
913 * @since 9
914 */
915 public synchronized void reseed(SecureRandomReseedParameters params) {
916 if (params == null) {
917 throw new IllegalArgumentException("params cannot be null");
918 }
919 secureRandomSpi.engineReseed(params);
920 }
921
922 // Declare serialVersionUID to be compatible with JDK1.1
923 static final long serialVersionUID = 4940670005562187L;
924
925 // Retain unused values serialized from JDK1.1
926 /**
927 * @serial
928 */
929 private byte[] state;
930 /**
931 * @serial
932 */
933 private MessageDigest digest = null;
934 /**
935 * @serial
936 *
937 * We know that the MessageDigest class does not implement
938 * java.io.Serializable. However, since this field is no longer
939 * used, it will always be NULL and won't affect the serialization
940 * of the {@code SecureRandom} class itself.
941 */
942 private byte[] randomBytes;
943 /**
944 * @serial
945 */
946 private int randomBytesUsed;
947 /**
948 * @serial
949 */
950 private long counter;
951 }
|