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