1 /*
2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.security;
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 minimally complies with the
42 * statistical random number generator tests specified in
43 * <a href="http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf">
44 * <i>FIPS 140-2, Security Requirements for Cryptographic Modules</i></a>,
45 * section 4.9.1.
46 * Additionally, {@code SecureRandom} must produce non-deterministic output.
47 * Therefore any seed material passed to a {@code SecureRandom} object must be
48 * unpredictable, and all {@code SecureRandom} output sequences must be
49 * cryptographically strong, as described in
50 * <a href="http://tools.ietf.org/html/rfc4086">
51 * <i>RFC 4086: Randomness Requirements for Security</i></a>.
52 *
53 * <p> Many {@code SecureRandom} implementations are in the form of a
54 * pseudo-random number generator (PRNG, also known as deterministic random
55 * bits generator or DRBG), which means they use a deterministic algorithm
56 * to produce a pseudo-random sequence from a random seed.
57 * Other implementations may produce true random numbers,
58 * and yet others may use a combination of both techniques.
59 *
60 * <p>A caller obtains a {@code SecureRandom} instance via the
61 * no-argument constructor or one of the {@code getInstance} methods.
62 * For example:
63 *
64 * <blockquote><pre>
65 * SecureRandom r1 = new SecureRandom();
66 * SecureRandom r2 = SecureRandom.getInstance("NativePRNG");
67 * SecureRandom r3 = SecureRandom.getInstance("DRBG",
68 * DrbgParameters.instantiation(128, RESEED_ONLY, null));</pre>
69 * </blockquote>
70 *
71 * <p> The third statement above returns a {@code SecureRandom} object of the
72 * specific algorithm supporting the specific instantiate parameters. The
73 * implementation's effective instantiated parameters must match this minimum
74 * request but is not necessarily the same. For example, even if the request
75 * does not require a certain feature, the actual instantiation can provide
76 * the feature. An implementation may lazily instantiate a {@code SecureRandom}
77 * until it's actually used, but the effective instantiate parameters must be
78 * determined right after it's created and {@link #getParameters()} should
79 * always return the same result unchanged.
80 *
81 * <p> Typical callers of {@code SecureRandom} invoke the following methods
82 * to retrieve random bytes:
83 *
84 * <blockquote><pre>
85 * SecureRandom random = new SecureRandom();
86 * byte[] bytes = new byte[20];
87 * random.nextBytes(bytes);</pre>
88 * </blockquote>
89 *
90 * <p> Callers may also invoke the {@link #generateSeed} method
91 * to generate a given number of seed bytes (to seed other random number
92 * generators, for example):
93 *
94 * <blockquote><pre>
95 * byte[] seed = random.generateSeed(20);</pre>
96 * </blockquote>
97 *
98 * <p> A newly created PRNG {@code SecureRandom} object is not seeded (except
99 * if it is created by {@link #SecureRandom(byte[])}). The first call to
100 * {@code nextBytes} will force it to seed itself from an implementation-
101 * specific entropy source. This self-seeding will not occur if {@code setSeed}
102 * was previously called.
103 *
104 * <p> A {@code SecureRandom} can be reseeded at any time by calling the
105 * {@code reseed} or {@code setSeed} method. The {@code reseed} method
106 * reads entropy input from its entropy source to reseed itself.
107 * The {@code setSeed} method requires the caller to provide the seed.
108 *
109 * <p> Please note that {@code reseed} may not be supported by all
110 * {@code SecureRandom} implementations.
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 * <h2> Thread safety </h2>
124 * {@code SecureRandom} objects are safe for use by multiple concurrent threads.
125 *
126 * @implSpec
127 * A {@code SecureRandom} service provider can advertise that it is thread-safe
128 * by setting the <a href=
129 * "{@docRoot}/../specs/security/standard-names.html#service-attributes">service
130 * provider attribute</a> "ThreadSafe" to "true" when registering the provider.
131 * Otherwise, this class will instead synchronize access to the following
132 * methods of the {@code SecureRandomSpi} implementation:
133 * <ul>
134 * <li>{@link SecureRandomSpi#engineSetSeed(byte[])}
135 * <li>{@link SecureRandomSpi#engineNextBytes(byte[])}
136 * <li>{@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)}
137 * <li>{@link SecureRandomSpi#engineGenerateSeed(int)}
138 * <li>{@link SecureRandomSpi#engineReseed(SecureRandomParameters)}
139 * </ul>
140 *
141 * @see java.security.SecureRandomSpi
142 * @see java.util.Random
143 *
144 * @author Benjamin Renaud
145 * @author Josh Bloch
146 * @since 1.1
147 */
148
149 public class SecureRandom extends java.util.Random {
150
151 private static final Debug pdebug =
152 Debug.getInstance("provider", "Provider");
153 private static final boolean skipDebug =
154 Debug.isOn("engine=") && !Debug.isOn("securerandom");
155
156 /**
157 * The provider.
158 *
159 * @serial
160 * @since 1.2
161 */
162 private Provider provider = null;
163
164 /**
165 * The provider implementation.
166 *
167 * @serial
168 * @since 1.2
169 */
170 private SecureRandomSpi secureRandomSpi = null;
171
172 /**
173 * Thread safety.
174 *
175 * @serial
176 * @since 9
177 */
178 private final boolean threadSafe;
179
180 /*
181 * The algorithm name of null if unknown.
182 *
183 * @serial
184 * @since 1.5
185 */
186 private String algorithm;
187
188 // Seed Generator
189 private static volatile SecureRandom seedGenerator;
190
191 /**
192 * Constructs a secure random number generator (RNG) implementing the
193 * default random number algorithm.
194 *
195 * <p> This constructor traverses the list of registered security Providers,
196 * starting with the most preferred Provider.
197 * A new {@code SecureRandom} object encapsulating the
198 * {@code SecureRandomSpi} implementation from the first
199 * Provider that supports a {@code SecureRandom} (RNG) algorithm is returned.
200 * If none of the Providers support a RNG algorithm,
201 * then an implementation-specific default is returned.
202 *
203 * <p> Note that the list of registered providers may be retrieved via
204 * the {@link Security#getProviders() Security.getProviders()} method.
205 *
206 * <p> See the {@code SecureRandom} section in the <a href=
207 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
208 * Java Security Standard Algorithm Names Specification</a>
209 * for information about standard RNG algorithm names.
210 */
211 public SecureRandom() {
212 /*
213 * This call to our superclass constructor will result in a call
214 * to our own {@code setSeed} method, which will return
215 * immediately when it is passed zero.
216 */
217 super(0);
218 getDefaultPRNG(false, null);
219 this.threadSafe = getThreadSafe();
220 }
221
222 private boolean getThreadSafe() {
223 if (provider == null || algorithm == null) {
224 return false;
225 } else {
226 return Boolean.parseBoolean(provider.getProperty(
227 "SecureRandom." + algorithm + " ThreadSafe", "false"));
228 }
229 }
230
231 /**
232 * Constructs a secure random number generator (RNG) implementing the
233 * default random number algorithm.
234 * The {@code SecureRandom} instance is seeded with the specified seed bytes.
235 *
236 * <p> This constructor traverses the list of registered security Providers,
237 * starting with the most preferred Provider.
238 * A new {@code SecureRandom} object encapsulating the
239 * {@code SecureRandomSpi} implementation from the first
240 * Provider that supports a {@code SecureRandom} (RNG) algorithm is returned.
241 * If none of the Providers support a RNG algorithm,
242 * then an implementation-specific default is returned.
243 *
244 * <p> Note that the list of registered providers may be retrieved via
245 * the {@link Security#getProviders() Security.getProviders()} method.
246 *
247 * <p> See the {@code SecureRandom} section in the <a href=
248 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
249 * Java Security Standard Algorithm Names Specification</a>
250 * for information about standard RNG algorithm names.
251 *
252 * @param seed the seed.
253 */
254 public SecureRandom(byte[] seed) {
255 super(0);
256 getDefaultPRNG(true, seed);
257 this.threadSafe = getThreadSafe();
258 }
259
260 private void getDefaultPRNG(boolean setSeed, byte[] seed) {
261 String prng = getPrngAlgorithm();
262 if (prng == null) {
263 // bummer, get the SUN implementation
264 prng = "SHA1PRNG";
265 this.secureRandomSpi = new sun.security.provider.SecureRandom();
266 this.provider = Providers.getSunProvider();
267 if (setSeed) {
268 this.secureRandomSpi.engineSetSeed(seed);
269 }
270 } else {
271 try {
272 SecureRandom random = SecureRandom.getInstance(prng);
273 this.secureRandomSpi = random.getSecureRandomSpi();
274 this.provider = random.getProvider();
275 if (setSeed) {
276 this.secureRandomSpi.engineSetSeed(seed);
277 }
278 } catch (NoSuchAlgorithmException nsae) {
279 // never happens, because we made sure the algorithm exists
280 throw new RuntimeException(nsae);
281 }
282 }
283 // JDK 1.1 based implementations subclass SecureRandom instead of
284 // SecureRandomSpi. They will also go through this code path because
285 // they must call a SecureRandom constructor as it is their superclass.
286 // If we are dealing with such an implementation, do not set the
287 // algorithm value as it would be inaccurate.
288 if (getClass() == SecureRandom.class) {
289 this.algorithm = prng;
290 }
291 }
292
293 /**
294 * Creates a {@code SecureRandom} object.
295 *
296 * @param secureRandomSpi the {@code SecureRandom} implementation.
297 * @param provider the provider.
298 */
299 protected SecureRandom(SecureRandomSpi secureRandomSpi,
300 Provider provider) {
301 this(secureRandomSpi, provider, null);
302 }
303
304 private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider,
305 String algorithm) {
306 super(0);
307 this.secureRandomSpi = secureRandomSpi;
308 this.provider = provider;
309 this.algorithm = algorithm;
310 this.threadSafe = getThreadSafe();
311
312 if (!skipDebug && pdebug != null) {
313 pdebug.println("SecureRandom." + algorithm +
314 " algorithm from: " + getProviderName());
315 }
316 }
317
318 private String getProviderName() {
319 return (provider == null) ? "(no provider)" : provider.getName();
320 }
321
322 /**
323 * Returns a {@code SecureRandom} object that implements the specified
324 * Random Number Generator (RNG) algorithm.
325 *
326 * <p> This method traverses the list of registered security Providers,
327 * starting with the most preferred Provider.
328 * A new {@code SecureRandom} object encapsulating the
329 * {@code SecureRandomSpi} implementation from the first
330 * Provider that supports the specified algorithm is returned.
331 *
332 * <p> Note that the list of registered providers may be retrieved via
333 * the {@link Security#getProviders() Security.getProviders()} method.
334 *
335 * @implNote
336 * The JDK Reference Implementation additionally uses the
337 * {@code jdk.security.provider.preferred}
338 * {@link Security#getProperty(String) Security} property to determine
339 * the preferred provider order for the specified algorithm. This
340 * may be different than the order of providers returned by
341 * {@link Security#getProviders() Security.getProviders()}.
342 *
343 * @param algorithm the name of the RNG algorithm.
344 * See the {@code SecureRandom} section in the <a href=
345 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
346 * Java Security Standard Algorithm Names Specification</a>
347 * for information about standard RNG algorithm names.
348 *
349 * @return the new {@code SecureRandom} object
350 *
351 * @throws NoSuchAlgorithmException if no {@code Provider} supports a
352 * {@code SecureRandomSpi} implementation for the
353 * specified algorithm
354 *
355 * @throws NullPointerException if {@code algorithm} is {@code null}
356 *
357 * @see Provider
358 *
359 * @since 1.2
360 */
361 public static SecureRandom getInstance(String algorithm)
362 throws NoSuchAlgorithmException {
363 Objects.requireNonNull(algorithm, "null algorithm name");
364 Instance instance = GetInstance.getInstance("SecureRandom",
365 SecureRandomSpi.class, algorithm);
366 return new SecureRandom((SecureRandomSpi)instance.impl,
367 instance.provider, algorithm);
368 }
369
370 /**
371 * Returns a {@code SecureRandom} object that implements the specified
372 * Random Number Generator (RNG) algorithm.
373 *
374 * <p> A new {@code SecureRandom} object encapsulating the
375 * {@code SecureRandomSpi} implementation from the specified provider
376 * is returned. The specified provider must be registered
377 * in the security provider list.
378 *
379 * <p> Note that the list of registered providers may be retrieved via
380 * the {@link Security#getProviders() Security.getProviders()} method.
381 *
382 * @param algorithm the name of the RNG algorithm.
383 * See the {@code SecureRandom} section in the <a href=
384 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
385 * Java Security Standard Algorithm Names Specification</a>
386 * for information about standard RNG algorithm names.
387 *
388 * @param provider the name of the provider.
389 *
390 * @return the new {@code SecureRandom} object
391 *
392 * @throws IllegalArgumentException if the provider name is {@code null}
393 * or empty
394 *
395 * @throws NoSuchAlgorithmException if a {@code SecureRandomSpi}
396 * implementation for the specified algorithm is not
397 * available from the specified provider
398 *
399 * @throws NoSuchProviderException if the specified provider is not
400 * registered in the security provider list
401 *
402 * @throws NullPointerException if {@code algorithm} is {@code null}
403 *
404 * @see Provider
405 *
406 * @since 1.2
407 */
408 public static SecureRandom getInstance(String algorithm, String provider)
409 throws NoSuchAlgorithmException, NoSuchProviderException {
410 Objects.requireNonNull(algorithm, "null algorithm name");
411 Instance instance = GetInstance.getInstance("SecureRandom",
412 SecureRandomSpi.class, algorithm, provider);
413 return new SecureRandom((SecureRandomSpi)instance.impl,
414 instance.provider, algorithm);
415 }
416
417 /**
418 * Returns a {@code SecureRandom} object that implements the specified
419 * Random Number Generator (RNG) algorithm.
420 *
421 * <p> A new {@code SecureRandom} object encapsulating the
422 * {@code SecureRandomSpi} implementation from the specified {@code Provider}
423 * object is returned. Note that the specified {@code Provider} object
424 * does not have to be registered in the provider list.
425 *
426 * @param algorithm the name of the RNG algorithm.
427 * See the {@code SecureRandom} section in the <a href=
428 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
429 * Java Security Standard Algorithm Names Specification</a>
430 * for information about standard RNG algorithm names.
431 *
432 * @param provider the provider.
433 *
434 * @return the new {@code SecureRandom} object
435 *
436 * @throws IllegalArgumentException if the specified provider is
437 * {@code null}
438 *
439 * @throws NoSuchAlgorithmException if a {@code SecureRandomSpi}
440 * implementation for the specified algorithm is not available
441 * from the specified {@code Provider} object
442 *
443 * @throws NullPointerException if {@code algorithm} is {@code null}
444 *
445 * @see Provider
446 *
447 * @since 1.4
448 */
449 public static SecureRandom getInstance(String algorithm,
450 Provider provider) throws NoSuchAlgorithmException {
451 Objects.requireNonNull(algorithm, "null algorithm name");
452 Instance instance = GetInstance.getInstance("SecureRandom",
453 SecureRandomSpi.class, algorithm, provider);
454 return new SecureRandom((SecureRandomSpi)instance.impl,
455 instance.provider, algorithm);
456 }
457
458 /**
459 * Returns a {@code SecureRandom} object that implements the specified
460 * Random Number Generator (RNG) algorithm and supports the specified
461 * {@code SecureRandomParameters} request.
462 *
463 * <p> This method traverses the list of registered security Providers,
464 * starting with the most preferred Provider.
465 * A new {@code SecureRandom} object encapsulating the
466 * {@code SecureRandomSpi} implementation from the first
467 * Provider that supports the specified algorithm and the specified
468 * {@code SecureRandomParameters} is returned.
469 *
470 * <p> Note that the list of registered providers may be retrieved via
471 * the {@link Security#getProviders() Security.getProviders()} method.
472 *
473 * @implNote
474 * The JDK Reference Implementation additionally uses the
475 * {@code jdk.security.provider.preferred} property to determine
476 * the preferred provider order for the specified algorithm. This
477 * may be different than the order of providers returned by
478 * {@link Security#getProviders() Security.getProviders()}.
479 *
480 * @param algorithm the name of the RNG algorithm.
481 * See the {@code SecureRandom} section in the <a href=
482 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
483 * Java Security Standard Algorithm Names Specification</a>
484 * for information about standard RNG algorithm names.
485 *
486 * @param params the {@code SecureRandomParameters}
487 * the newly created {@code SecureRandom} object must support.
488 *
489 * @return the new {@code SecureRandom} object
490 *
491 * @throws IllegalArgumentException if the specified params is
492 * {@code null}
493 *
494 * @throws NoSuchAlgorithmException if no Provider supports a
495 * {@code SecureRandomSpi} implementation for the specified
496 * algorithm and parameters
497 *
498 * @throws NullPointerException if {@code algorithm} is {@code null}
499 *
500 * @see Provider
501 *
502 * @since 9
503 */
504 public static SecureRandom getInstance(
505 String algorithm, SecureRandomParameters params)
506 throws NoSuchAlgorithmException {
507 Objects.requireNonNull(algorithm, "null algorithm name");
508 if (params == null) {
509 throw new IllegalArgumentException("params cannot be null");
510 }
511 Instance instance = GetInstance.getInstance("SecureRandom",
512 SecureRandomSpi.class, algorithm, params);
513 return new SecureRandom((SecureRandomSpi)instance.impl,
514 instance.provider, algorithm);
515 }
516
517 /**
518 * Returns a {@code SecureRandom} object that implements the specified
519 * Random Number Generator (RNG) algorithm and supports the specified
520 * {@code SecureRandomParameters} request.
521 *
522 * <p> A new {@code SecureRandom} object encapsulating the
523 * {@code SecureRandomSpi} implementation from the specified provider
524 * is returned. The specified provider must be registered
525 * in the security provider list.
526 *
527 * <p> Note that the list of registered providers may be retrieved via
528 * the {@link Security#getProviders() Security.getProviders()} method.
529 *
530 * @param algorithm the name of the RNG algorithm.
531 * See the {@code SecureRandom} section in the <a href=
532 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
533 * Java Security Standard Algorithm Names Specification</a>
534 * for information about standard RNG algorithm names.
535 *
536 * @param params the {@code SecureRandomParameters}
537 * the newly created {@code SecureRandom} object must support.
538 *
539 * @param provider the name of the provider.
540 *
541 * @return the new {@code SecureRandom} object
542 *
543 * @throws IllegalArgumentException if the provider name is {@code null}
544 * or empty, or params is {@code null}
545 *
546 * @throws NoSuchAlgorithmException if the specified provider does not
547 * support a {@code SecureRandomSpi} implementation for the
548 * specified algorithm and parameters
549 *
550 * @throws NoSuchProviderException if the specified provider is not
551 * registered in the security provider list
552 *
553 * @throws NullPointerException if {@code algorithm} is {@code null}
554 *
555 * @see Provider
556 *
557 * @since 9
558 */
559 public static SecureRandom getInstance(String algorithm,
560 SecureRandomParameters params, String provider)
561 throws NoSuchAlgorithmException, NoSuchProviderException {
562 Objects.requireNonNull(algorithm, "null algorithm name");
563 if (params == null) {
564 throw new IllegalArgumentException("params cannot be null");
565 }
566 Instance instance = GetInstance.getInstance("SecureRandom",
567 SecureRandomSpi.class, algorithm, params, provider);
568 return new SecureRandom((SecureRandomSpi)instance.impl,
569 instance.provider, algorithm);
570 }
571
572 /**
573 * Returns a {@code SecureRandom} object that implements the specified
574 * Random Number Generator (RNG) algorithm and supports the specified
575 * {@code SecureRandomParameters} request.
576 *
577 * <p> A new {@code SecureRandom} object encapsulating the
578 * {@code SecureRandomSpi} implementation from the specified
579 * {@code Provider} object is returned. Note that the specified
580 * {@code Provider} object does not have to be registered in the
581 * provider list.
582 *
583 * @param algorithm the name of the RNG algorithm.
584 * See the {@code SecureRandom} section in the <a href=
585 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
586 * Java Security Standard Algorithm Names Specification</a>
587 * for information about standard RNG algorithm names.
588 *
589 * @param params the {@code SecureRandomParameters}
590 * the newly created {@code SecureRandom} object must support.
591 *
592 * @param provider the provider.
593 *
594 * @return the new {@code SecureRandom} object
595 *
596 * @throws IllegalArgumentException if the specified provider or params
597 * is {@code null}
598 *
599 * @throws NoSuchAlgorithmException if the specified provider does not
600 * support a {@code SecureRandomSpi} implementation for the
601 * specified algorithm and parameters
602 *
603 * @throws NullPointerException if {@code algorithm} is {@code null}
604 *
605 * @see Provider
606 *
607 * @since 9
608 */
609 public static SecureRandom getInstance(String algorithm,
610 SecureRandomParameters params, Provider provider)
611 throws NoSuchAlgorithmException {
612 Objects.requireNonNull(algorithm, "null algorithm name");
613 if (params == null) {
614 throw new IllegalArgumentException("params cannot be null");
615 }
616 Instance instance = GetInstance.getInstance("SecureRandom",
617 SecureRandomSpi.class, algorithm, params, provider);
618 return new SecureRandom((SecureRandomSpi)instance.impl,
619 instance.provider, algorithm);
620 }
621
622 /**
623 * Returns the {@code SecureRandomSpi} of this {@code SecureRandom} object.
624 */
625 SecureRandomSpi getSecureRandomSpi() {
626 return secureRandomSpi;
627 }
628
629 /**
630 * Returns the provider of this {@code SecureRandom} object.
631 *
632 * @return the provider of this {@code SecureRandom} object.
633 */
634 public final Provider getProvider() {
635 return provider;
636 }
637
638 /**
639 * Returns the name of the algorithm implemented by this
640 * {@code SecureRandom} object.
641 *
642 * @return the name of the algorithm or {@code unknown}
643 * if the algorithm name cannot be determined.
644 * @since 1.5
645 */
646 public String getAlgorithm() {
647 return Objects.toString(algorithm, "unknown");
648 }
649
650 /**
651 * Returns a Human-readable string representation of this
652 * {@code SecureRandom}.
653 *
654 * @return the string representation
655 */
656 @Override
657 public String toString() {
658 return secureRandomSpi.toString();
659 }
660
661 /**
662 * Returns the effective {@link SecureRandomParameters} for this
663 * {@code SecureRandom} instance.
664 * <p>
665 * The returned value can be different from the
666 * {@code SecureRandomParameters} object passed into a {@code getInstance}
667 * method, but it cannot change during the lifetime of this
668 * {@code SecureRandom} object.
669 * <p>
670 * A caller can use the returned value to find out what features this
671 * {@code SecureRandom} supports.
672 *
673 * @return the effective {@link SecureRandomParameters} parameters,
674 * or {@code null} if no parameters were used.
675 *
676 * @since 9
677 * @see SecureRandomSpi
678 */
679 public SecureRandomParameters getParameters() {
680 return secureRandomSpi.engineGetParameters();
681 }
682
683 /**
684 * Reseeds this random object with the given seed. The seed supplements,
685 * rather than replaces, the existing seed. Thus, repeated calls are
686 * guaranteed never to reduce randomness.
687 * <p>
688 * A PRNG {@code SecureRandom} will not seed itself automatically if
689 * {@code setSeed} is called before any {@code nextBytes} or {@code reseed}
690 * calls. The caller should make sure that the {@code seed} argument
691 * contains enough entropy for the security of this {@code SecureRandom}.
692 *
693 * @param seed the seed.
694 *
695 * @see #getSeed
696 */
697 public void setSeed(byte[] seed) {
698 if (threadSafe) {
699 secureRandomSpi.engineSetSeed(seed);
700 } else {
701 synchronized (this) {
702 secureRandomSpi.engineSetSeed(seed);
703 }
704 }
705 }
706
707 /**
708 * Reseeds this random object, using the eight bytes contained
709 * in the given {@code long seed}. The given seed supplements,
710 * rather than replaces, the existing seed. Thus, repeated calls
711 * are guaranteed never to reduce randomness.
712 *
713 * <p>This method is defined for compatibility with
714 * {@code java.util.Random}.
715 *
716 * @param seed the seed.
717 *
718 * @see #getSeed
719 */
720 @Override
721 public void setSeed(long seed) {
722 /*
723 * Ignore call from super constructor (as well as any other calls
724 * unfortunate enough to be passing 0). It's critical that we
725 * ignore call from superclass constructor, as digest has not
726 * yet been initialized at that point.
727 */
728 if (seed != 0) {
729 setSeed(longToByteArray(seed));
730 }
731 }
732
733 /**
734 * Generates a user-specified number of random bytes.
735 *
736 * @param bytes the array to be filled in with random bytes.
737 */
738 @Override
739 public void nextBytes(byte[] bytes) {
740 if (threadSafe) {
741 secureRandomSpi.engineNextBytes(bytes);
742 } else {
743 synchronized (this) {
744 secureRandomSpi.engineNextBytes(bytes);
745 }
746 }
747 }
748
749 /**
750 * Generates a user-specified number of random bytes with
751 * additional parameters.
752 *
753 * @param bytes the array to be filled in with random bytes
754 * @param params additional parameters
755 * @throws NullPointerException if {@code bytes} is null
756 * @throws UnsupportedOperationException if the underlying provider
757 * implementation has not overridden this method
758 * @throws IllegalArgumentException if {@code params} is {@code null},
759 * illegal or unsupported by this {@code SecureRandom}
760 *
761 * @since 9
762 */
763 public void nextBytes(byte[] bytes, SecureRandomParameters params) {
764 if (params == null) {
765 throw new IllegalArgumentException("params cannot be null");
766 }
767 if (threadSafe) {
768 secureRandomSpi.engineNextBytes(
769 Objects.requireNonNull(bytes), params);
770 } else {
771 synchronized (this) {
772 secureRandomSpi.engineNextBytes(
773 Objects.requireNonNull(bytes), params);
774 }
775 }
776 }
777
778 /**
779 * Generates an integer containing the user-specified number of
780 * pseudo-random bits (right justified, with leading zeros). This
781 * method overrides a {@code java.util.Random} method, and serves
782 * to provide a source of random bits to all of the methods inherited
783 * from that class (for example, {@code nextInt},
784 * {@code nextLong}, and {@code nextFloat}).
785 *
786 * @param numBits number of pseudo-random bits to be generated, where
787 * {@code 0 <= numBits <= 32}.
788 *
789 * @return an {@code int} containing the user-specified number
790 * of pseudo-random bits (right justified, with leading zeros).
791 */
792 @Override
793 protected final int next(int numBits) {
794 int numBytes = (numBits+7)/8;
795 byte[] b = new byte[numBytes];
796 int next = 0;
797
798 nextBytes(b);
799 for (int i = 0; i < numBytes; i++) {
800 next = (next << 8) + (b[i] & 0xFF);
801 }
802
803 return next >>> (numBytes*8 - numBits);
804 }
805
806 /**
807 * Returns the given number of seed bytes, computed using the seed
808 * generation algorithm that this class uses to seed itself. This
809 * call may be used to seed other random number generators.
810 *
811 * <p>This method is only included for backwards compatibility.
812 * The caller is encouraged to use one of the alternative
813 * {@code getInstance} methods to obtain a {@code SecureRandom} object, and
814 * then call the {@code generateSeed} method to obtain seed bytes
815 * from that object.
816 *
817 * @param numBytes the number of seed bytes to generate.
818 *
819 * @throws IllegalArgumentException if {@code numBytes} is negative
820 * @return the seed bytes.
821 *
822 * @see #setSeed
823 */
824 public static byte[] getSeed(int numBytes) {
825 SecureRandom seedGen = seedGenerator;
826 if (seedGen == null) {
827 seedGen = new SecureRandom();
828 seedGenerator = seedGen;
829 }
830 return seedGen.generateSeed(numBytes);
831 }
832
833 /**
834 * Returns the given number of seed bytes, computed using the seed
835 * generation algorithm that this class uses to seed itself. This
836 * call may be used to seed other random number generators.
837 *
838 * @param numBytes the number of seed bytes to generate.
839 * @throws IllegalArgumentException if {@code numBytes} is negative
840 * @return the seed bytes.
841 */
842 public byte[] generateSeed(int numBytes) {
843 if (numBytes < 0) {
844 throw new IllegalArgumentException("numBytes cannot be negative");
845 }
846 if (threadSafe) {
847 return secureRandomSpi.engineGenerateSeed(numBytes);
848 } else {
849 synchronized (this) {
850 return secureRandomSpi.engineGenerateSeed(numBytes);
851 }
852 }
853 }
854
855 /**
856 * Helper function to convert a long into a byte array (least significant
857 * byte first).
858 */
859 private static byte[] longToByteArray(long l) {
860 byte[] retVal = new byte[8];
861
862 for (int i = 0; i < 8; i++) {
863 retVal[i] = (byte) l;
864 l >>= 8;
865 }
866
867 return retVal;
868 }
869
870 /**
871 * Gets a default PRNG algorithm by looking through all registered
872 * providers. Returns the first PRNG algorithm of the first provider that
873 * has registered a {@code SecureRandom} implementation, or null if none of
874 * the registered providers supplies a {@code SecureRandom} implementation.
875 */
876 private static String getPrngAlgorithm() {
877 for (Provider p : Providers.getProviderList().providers()) {
878 for (Service s : p.getServices()) {
879 if (s.getType().equals("SecureRandom")) {
880 return s.getAlgorithm();
881 }
882 }
883 }
884 return null;
885 }
886
887 /*
888 * Lazily initialize since Pattern.compile() is heavy.
889 * Effective Java (2nd Edition), Item 71.
890 */
891 private static final class StrongPatternHolder {
892 /*
893 * Entries are alg:prov separated by ,
894 * Allow for prepended/appended whitespace between entries.
895 *
896 * Capture groups:
897 * 1 - alg
898 * 2 - :prov (optional)
899 * 3 - prov (optional)
900 * 4 - ,nextEntry (optional)
901 * 5 - nextEntry (optional)
902 */
903 private static Pattern pattern =
904 Pattern.compile(
905 "\\s*([\\S&&[^:,]]*)(\\:([\\S&&[^,]]*))?\\s*(\\,(.*))?");
906 }
907
908 /**
909 * Returns a {@code SecureRandom} object that was selected by using
910 * the algorithms/providers specified in the {@code
911 * securerandom.strongAlgorithms} {@link Security} property.
912 * <p>
913 * Some situations require strong random values, such as when
914 * creating high-value/long-lived secrets like RSA public/private
915 * keys. To help guide applications in selecting a suitable strong
916 * {@code SecureRandom} implementation, Java distributions
917 * include a list of known strong {@code SecureRandom}
918 * implementations in the {@code securerandom.strongAlgorithms}
919 * Security property.
920 * <p>
921 * Every implementation of the Java platform is required to
922 * support at least one strong {@code SecureRandom} implementation.
923 *
924 * @return a strong {@code SecureRandom} implementation as indicated
925 * by the {@code securerandom.strongAlgorithms} Security property
926 *
927 * @throws NoSuchAlgorithmException if no algorithm is available
928 *
929 * @see Security#getProperty(String)
930 *
931 * @since 1.8
932 */
933 public static SecureRandom getInstanceStrong()
934 throws NoSuchAlgorithmException {
935
936 String property = AccessController.doPrivileged(
937 new PrivilegedAction<>() {
938 @Override
939 public String run() {
940 return Security.getProperty(
941 "securerandom.strongAlgorithms");
942 }
943 });
944
945 if (property == null || property.isEmpty()) {
946 throw new NoSuchAlgorithmException(
947 "Null/empty securerandom.strongAlgorithms Security Property");
948 }
949
950 String remainder = property;
951 while (remainder != null) {
952 Matcher m;
953 if ((m = StrongPatternHolder.pattern.matcher(
954 remainder)).matches()) {
955
956 String alg = m.group(1);
957 String prov = m.group(3);
958
959 try {
960 if (prov == null) {
961 return SecureRandom.getInstance(alg);
962 } else {
963 return SecureRandom.getInstance(alg, prov);
964 }
965 } catch (NoSuchAlgorithmException |
966 NoSuchProviderException e) {
967 }
968 remainder = m.group(5);
969 } else {
970 remainder = null;
971 }
972 }
973
974 throw new NoSuchAlgorithmException(
975 "No strong SecureRandom impls available: " + property);
976 }
977
978 /**
979 * Reseeds this {@code SecureRandom} with entropy input read from its
980 * entropy source.
981 *
982 * @throws UnsupportedOperationException if the underlying provider
983 * implementation has not overridden this method.
984 *
985 * @since 9
986 */
987 public void reseed() {
988 if (threadSafe) {
989 secureRandomSpi.engineReseed(null);
990 } else {
991 synchronized (this) {
992 secureRandomSpi.engineReseed(null);
993 }
994 }
995 }
996
997 /**
998 * Reseeds this {@code SecureRandom} with entropy input read from its
999 * entropy source with additional parameters.
1000 * <p>
1001 * Note that entropy is obtained from an entropy source. While
1002 * some data in {@code params} may contain entropy, its main usage is to
1003 * provide diversity.
1004 *
1005 * @param params extra parameters
1006 * @throws UnsupportedOperationException if the underlying provider
1007 * implementation has not overridden this method.
1008 * @throws IllegalArgumentException if {@code params} is {@code null},
1009 * illegal or unsupported by this {@code SecureRandom}
1010 *
1011 * @since 9
1012 */
1013 public void reseed(SecureRandomParameters params) {
1014 if (params == null) {
1015 throw new IllegalArgumentException("params cannot be null");
1016 }
1017 if (threadSafe) {
1018 secureRandomSpi.engineReseed(params);
1019 } else {
1020 synchronized (this) {
1021 secureRandomSpi.engineReseed(params);
1022 }
1023 }
1024 }
1025
1026 // Declare serialVersionUID to be compatible with JDK1.1
1027 static final long serialVersionUID = 4940670005562187L;
1028
1029 // Retain unused values serialized from JDK1.1
1030 /**
1031 * @serial
1032 */
1033 private byte[] state;
1034 /**
1035 * @serial
1036 */
1037 private MessageDigest digest = null;
1038 /**
1039 * @serial
1040 *
1041 * We know that the MessageDigest class does not implement
1042 * java.io.Serializable. However, since this field is no longer
1043 * used, it will always be NULL and won't affect the serialization
1044 * of the {@code SecureRandom} class itself.
1045 */
1046 private byte[] randomBytes;
1047 /**
1048 * @serial
1049 */
1050 private int randomBytesUsed;
1051 /**
1052 * @serial
1053 */
1054 private long counter;
1055 }
1056