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