Home | History | Annotate | Download | only in security
      1 /*
      2  * Copyright (c) 1996, 2013, 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 import java.util.function.Function;
     33 
     34 import dalvik.system.VMRuntime;
     35 import sun.security.jca.*;
     36 import sun.security.jca.GetInstance.Instance;
     37 
     38 /**
     39  * This class provides a cryptographically strong random number
     40  * generator (RNG).
     41  *
     42  * <p>A cryptographically strong random number
     43  * minimally complies with the statistical random number generator tests
     44  * specified in <a href="http://csrc.nist.gov/cryptval/140-2.htm">
     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://www.ietf.org/rfc/rfc1750.txt">
     52  * <i>RFC 1750: Randomness Recommendations 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  * The SHA1PRNG algorithm from the Crypto provider has been deprecated as it was insecure, and also
     89  * incorrectly used by some apps as a key derivation function. See
     90  * <a href="http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html">
     91  * Security &quot;Crypto&quot; provider deprecated in Android N</a> for details.
     92  *
     93  * @see java.security.SecureRandomSpi
     94  * @see java.util.Random
     95  *
     96  * @author Benjamin Renaud
     97  * @author Josh Bloch
     98  */
     99 
    100 public class SecureRandom extends java.util.Random {
    101 
    102     // Android-removed: this debugging mechanism is not used in Android.
    103     /*
    104     private static final Debug pdebug =
    105                         Debug.getInstance("provider", "Provider");
    106     private static final boolean skipDebug =
    107         Debug.isOn("engine=") && !Debug.isOn("securerandom");
    108     */
    109     // END Android-removed
    110 
    111     /**
    112      * The provider.
    113      *
    114      * @serial
    115      * @since 1.2
    116      */
    117     private Provider provider = null;
    118 
    119     /**
    120      * The provider implementation.
    121      *
    122      * @serial
    123      * @since 1.2
    124      */
    125     private SecureRandomSpi secureRandomSpi = null;
    126 
    127     /*
    128      * The algorithm name of null if unknown.
    129      *
    130      * @serial
    131      * @since 1.5
    132      */
    133     private String algorithm;
    134 
    135     // Seed Generator
    136     private static volatile SecureRandom seedGenerator = null;
    137 
    138     /**
    139      * Constructs a secure random number generator (RNG) implementing the
    140      * default random number algorithm.
    141      *
    142      * <p> This constructor traverses the list of registered security Providers,
    143      * starting with the most preferred Provider.
    144      * A new SecureRandom object encapsulating the
    145      * SecureRandomSpi implementation from the first
    146      * Provider that supports a SecureRandom (RNG) algorithm is returned.
    147      * If none of the Providers support a RNG algorithm,
    148      * then an implementation-specific default is returned.
    149      *
    150      * <p> Note that the list of registered providers may be retrieved via
    151      * the {@link Security#getProviders() Security.getProviders()} method.
    152      *
    153      * <p> See the SecureRandom section in the <a href=
    154      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
    155      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    156      * for information about standard RNG algorithm names.
    157      *
    158      * <p> The returned SecureRandom object has not been seeded.  To seed the
    159      * returned object, call the {@code setSeed} method.
    160      * If {@code setSeed} is not called, the first call to
    161      * {@code nextBytes} will force the SecureRandom object to seed itself.
    162      * This self-seeding will not occur if {@code setSeed} was
    163      * previously called.
    164      */
    165     public SecureRandom() {
    166         /*
    167          * This call to our superclass constructor will result in a call
    168          * to our own {@code setSeed} method, which will return
    169          * immediately when it is passed zero.
    170          */
    171         super(0);
    172         getDefaultPRNG(false, null);
    173     }
    174 
    175     /**
    176      * Constructs a secure random number generator (RNG) implementing the
    177      * default random number algorithm.
    178      * The SecureRandom instance is seeded with the specified seed bytes.
    179      *
    180      * <p> This constructor traverses the list of registered security Providers,
    181      * starting with the most preferred Provider.
    182      * A new SecureRandom object encapsulating the
    183      * SecureRandomSpi implementation from the first
    184      * Provider that supports a SecureRandom (RNG) algorithm is returned.
    185      * If none of the Providers support a RNG algorithm,
    186      * then an implementation-specific default is returned.
    187      *
    188      * <p> Note that the list of registered providers may be retrieved via
    189      * the {@link Security#getProviders() Security.getProviders()} method.
    190      *
    191      * <p> See the SecureRandom section in the <a href=
    192      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
    193      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    194      * for information about standard RNG algorithm names.
    195      *
    196      * @param seed the seed.
    197      */
    198     public SecureRandom(byte seed[]) {
    199         super(0);
    200         getDefaultPRNG(true, seed);
    201     }
    202 
    203     private void getDefaultPRNG(boolean setSeed, byte[] seed) {
    204         String prng = getPrngAlgorithm();
    205         if (prng == null) {
    206             // Android-changed: This should never happen, we always provide a SecureRandom
    207             throw new IllegalStateException("No SecureRandom implementation!");
    208         } else {
    209             try {
    210                 SecureRandom random = SecureRandom.getInstance(prng);
    211                 this.secureRandomSpi = random.getSecureRandomSpi();
    212                 this.provider = random.getProvider();
    213                 if (setSeed) {
    214                     this.secureRandomSpi.engineSetSeed(seed);
    215                 }
    216             } catch (NoSuchAlgorithmException nsae) {
    217                 // never happens, because we made sure the algorithm exists
    218                 throw new RuntimeException(nsae);
    219             }
    220         }
    221         // JDK 1.1 based implementations subclass SecureRandom instead of
    222         // SecureRandomSpi. They will also go through this code path because
    223         // they must call a SecureRandom constructor as it is their superclass.
    224         // If we are dealing with such an implementation, do not set the
    225         // algorithm value as it would be inaccurate.
    226         if (getClass() == SecureRandom.class) {
    227             this.algorithm = prng;
    228         }
    229     }
    230 
    231     /**
    232      * Creates a SecureRandom object.
    233      *
    234      * @param secureRandomSpi the SecureRandom implementation.
    235      * @param provider the provider.
    236      */
    237     protected SecureRandom(SecureRandomSpi secureRandomSpi,
    238                            Provider provider) {
    239         this(secureRandomSpi, provider, null);
    240     }
    241 
    242     private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider,
    243             String algorithm) {
    244         super(0);
    245         this.secureRandomSpi = secureRandomSpi;
    246         this.provider = provider;
    247         this.algorithm = algorithm;
    248 
    249         // BEGIN Android-removed: this debugging mechanism is not supported in Android.
    250         /*
    251         if (!skipDebug && pdebug != null) {
    252             pdebug.println("SecureRandom." + algorithm +
    253                 " algorithm from: " + this.provider.getName());
    254         }
    255         */
    256         // END Android-removed
    257     }
    258 
    259     /**
    260      * Returns a SecureRandom object that implements the specified
    261      * Random Number Generator (RNG) algorithm.
    262      *
    263      * <p> This method traverses the list of registered security Providers,
    264      * starting with the most preferred Provider.
    265      * A new SecureRandom object encapsulating the
    266      * SecureRandomSpi implementation from the first
    267      * Provider that supports the specified algorithm is returned.
    268      *
    269      * <p> Note that the list of registered providers may be retrieved via
    270      * the {@link Security#getProviders() Security.getProviders()} method.
    271      *
    272      * <p> The returned SecureRandom object has not been seeded.  To seed the
    273      * returned object, call the {@code setSeed} method.
    274      * If {@code setSeed} is not called, the first call to
    275      * {@code nextBytes} will force the SecureRandom object to seed itself.
    276      * This self-seeding will not occur if {@code setSeed} was
    277      * previously called.
    278      *
    279      * @param algorithm the name of the RNG algorithm.
    280      * See the SecureRandom section in the <a href=
    281      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
    282      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    283      * for information about standard RNG algorithm names.
    284      *
    285      * @return the new SecureRandom object.
    286      *
    287      * @exception NoSuchAlgorithmException if no Provider supports a
    288      *          SecureRandomSpi implementation for the
    289      *          specified algorithm.
    290      *
    291      * @see Provider
    292      *
    293      * @since 1.2
    294      */
    295     public static SecureRandom getInstance(String algorithm)
    296             throws NoSuchAlgorithmException {
    297         Instance instance = GetInstance.getInstance("SecureRandom",
    298             SecureRandomSpi.class, algorithm);
    299         return new SecureRandom((SecureRandomSpi)instance.impl,
    300             instance.provider, algorithm);
    301     }
    302 
    303     // BEGIN Android-added: Support for Crypto provider workaround
    304     /**
    305      * Maximum SDK version for which the workaround for the Crypto provider is in place.
    306      *
    307      * <p> We provide instances from the Crypto provider (although the provider is not installed) to
    308      * apps targeting M or earlier versions of the SDK.
    309      *
    310      * <p> Default is 23 (M). We have it as a field for testability and it shouldn't be changed.
    311      *
    312      * @hide
    313      */
    314     public static final int DEFAULT_SDK_TARGET_FOR_CRYPTO_PROVIDER_WORKAROUND = 23;
    315 
    316     private static int sdkTargetForCryptoProviderWorkaround =
    317             DEFAULT_SDK_TARGET_FOR_CRYPTO_PROVIDER_WORKAROUND;
    318 
    319     /**
    320      * Only for testing.
    321      *
    322      * @hide
    323      */
    324     public static void setSdkTargetForCryptoProviderWorkaround(int sdkTargetVersion) {
    325         sdkTargetForCryptoProviderWorkaround = sdkTargetVersion;
    326     }
    327 
    328     /**
    329      * Only for testing.
    330      *
    331      * @hide
    332      */
    333     public static int getSdkTargetForCryptoProviderWorkaround() {
    334         return sdkTargetForCryptoProviderWorkaround;
    335     }
    336     // END Android-added: Support for Crypto provider workaround
    337 
    338     /**
    339      * Returns a SecureRandom object that implements the specified
    340      * Random Number Generator (RNG) algorithm.
    341      *
    342      * <p> A new SecureRandom object encapsulating the
    343      * SecureRandomSpi implementation from the specified provider
    344      * is returned.  The specified provider must be registered
    345      * in the security provider list.
    346      *
    347      * <p> Note that the list of registered providers may be retrieved via
    348      * the {@link Security#getProviders() Security.getProviders()} method.
    349      *
    350      * <p> The returned SecureRandom object has not been seeded.  To seed the
    351      * returned object, call the {@code setSeed} method.
    352      * If {@code setSeed} is not called, the first call to
    353      * {@code nextBytes} will force the SecureRandom object to seed itself.
    354      * This self-seeding will not occur if {@code setSeed} was
    355      * previously called.
    356      *
    357      * @param algorithm the name of the RNG algorithm.
    358      * See the SecureRandom section in the <a href=
    359      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
    360      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    361      * for information about standard RNG algorithm names.
    362      *
    363      * @param provider the name of the provider.
    364      *
    365      * @return the new SecureRandom object.
    366      *
    367      * @exception NoSuchAlgorithmException if a SecureRandomSpi
    368      *          implementation for the specified algorithm is not
    369      *          available from the specified provider.
    370      *
    371      * @exception NoSuchProviderException if the specified provider is not
    372      *          registered in the security provider list.
    373      *
    374      * @exception IllegalArgumentException if the provider name is null
    375      *          or empty.
    376      *
    377      * @see Provider
    378      *
    379      * @since 1.2
    380      */
    381     public static SecureRandom getInstance(String algorithm, String provider)
    382             throws NoSuchAlgorithmException, NoSuchProviderException {
    383         try {
    384             Instance instance = GetInstance.getInstance("SecureRandom",
    385                     SecureRandomSpi.class, algorithm, provider);
    386             return new SecureRandom((SecureRandomSpi) instance.impl,
    387                     instance.provider, algorithm);
    388         // BEGIN Android-added: Crypto provider deprecation
    389         } catch (NoSuchProviderException nspe) {
    390             if ("Crypto".equals(provider)) {
    391                 System.logE(" ********** PLEASE READ ************ ");
    392                 System.logE(" * ");
    393                 System.logE(" * New versions of the Android SDK no longer support the Crypto provider.");
    394                 System.logE(" * If your app was relying on setSeed() to derive keys from strings, you");
    395                 System.logE(" * should switch to using SecretKeySpec to load raw key bytes directly OR");
    396                 System.logE(" * use a real key derivation function (KDF). See advice here : ");
    397                 System.logE(" * http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html ");
    398                 System.logE(" *********************************** ");
    399                 if (VMRuntime.getRuntime().getTargetSdkVersion()
    400                         <= sdkTargetForCryptoProviderWorkaround) {
    401                     System.logE(" Returning an instance of SecureRandom from the Crypto provider");
    402                     System.logE(" as a temporary measure so that the apps targeting earlier SDKs");
    403                     System.logE(" keep working. Please do not rely on the presence of the Crypto");
    404                     System.logE(" provider in the codebase, as our plan is to delete it");
    405                     System.logE(" completely in the future.");
    406                     return getInstanceFromCryptoProvider(algorithm);
    407                 }
    408             }
    409 
    410             throw nspe;
    411         }
    412     }
    413 
    414     private static SecureRandom getInstanceFromCryptoProvider(String algorithm)
    415             throws NoSuchAlgorithmException {
    416         Provider cryptoProvider;
    417         try {
    418             cryptoProvider = (Provider) SecureRandom.class.getClassLoader()
    419                     .loadClass(
    420                             "org.apache.harmony.security.provider.crypto.CryptoProvider")
    421                     .newInstance();
    422         } catch (Exception e) {
    423             throw new RuntimeException(e);
    424         }
    425         Service service = cryptoProvider.getService("SecureRandom", algorithm);
    426         Instance instance = GetInstance.getInstance(service, SecureRandomSpi.class);
    427         return new SecureRandom(
    428                 (SecureRandomSpi) instance.impl, instance.provider, algorithm);
    429     }
    430     // END Android-added: Crypto provider deprecation
    431 
    432     /**
    433      * Returns a SecureRandom object that implements the specified
    434      * Random Number Generator (RNG) algorithm.
    435      *
    436      * <p> A new SecureRandom object encapsulating the
    437      * SecureRandomSpi implementation from the specified Provider
    438      * object is returned.  Note that the specified Provider object
    439      * does not have to be registered in the provider list.
    440      *
    441      * <p> The returned SecureRandom object has not been seeded.  To seed the
    442      * returned object, call the {@code setSeed} method.
    443      * If {@code setSeed} is not called, the first call to
    444      * {@code nextBytes} will force the SecureRandom object to seed itself.
    445      * This self-seeding will not occur if {@code setSeed} was
    446      * previously called.
    447      *
    448      * @param algorithm the name of the RNG algorithm.
    449      * See the SecureRandom section in the <a href=
    450      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
    451      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    452      * for information about standard RNG algorithm names.
    453      *
    454      * @param provider the provider.
    455      *
    456      * @return the new SecureRandom object.
    457      *
    458      * @exception NoSuchAlgorithmException if a SecureRandomSpi
    459      *          implementation for the specified algorithm is not available
    460      *          from the specified Provider object.
    461      *
    462      * @exception IllegalArgumentException if the specified provider is null.
    463      *
    464      * @see Provider
    465      *
    466      * @since 1.4
    467      */
    468     public static SecureRandom getInstance(String algorithm,
    469             Provider provider) throws NoSuchAlgorithmException {
    470         Instance instance = GetInstance.getInstance("SecureRandom",
    471             SecureRandomSpi.class, algorithm, provider);
    472         return new SecureRandom((SecureRandomSpi)instance.impl,
    473             instance.provider, algorithm);
    474     }
    475 
    476     /**
    477      * Returns the SecureRandomSpi of this SecureRandom object.
    478      */
    479     SecureRandomSpi getSecureRandomSpi() {
    480         return secureRandomSpi;
    481     }
    482 
    483     /**
    484      * Returns the provider of this SecureRandom object.
    485      *
    486      * @return the provider of this SecureRandom object.
    487      */
    488     public final Provider getProvider() {
    489         return provider;
    490     }
    491 
    492     /**
    493      * Returns the name of the algorithm implemented by this SecureRandom
    494      * object.
    495      *
    496      * @return the name of the algorithm or {@code unknown}
    497      *          if the algorithm name cannot be determined.
    498      * @since 1.5
    499      */
    500     public String getAlgorithm() {
    501         return (algorithm != null) ? algorithm : "unknown";
    502     }
    503 
    504     /**
    505      * Reseeds this random object. The given seed supplements, rather than
    506      * replaces, the existing seed. Thus, repeated calls are guaranteed
    507      * never to reduce randomness.
    508      *
    509      * @param seed the seed.
    510      *
    511      * @see #getSeed
    512      */
    513     synchronized public void setSeed(byte[] seed) {
    514         secureRandomSpi.engineSetSeed(seed);
    515     }
    516 
    517     /**
    518      * Reseeds this random object, using the eight bytes contained
    519      * in the given {@code long seed}. The given seed supplements,
    520      * rather than replaces, the existing seed. Thus, repeated calls
    521      * are guaranteed never to reduce randomness.
    522      *
    523      * <p>This method is defined for compatibility with
    524      * {@code java.util.Random}.
    525      *
    526      * @param seed the seed.
    527      *
    528      * @see #getSeed
    529      */
    530     @Override
    531     public void setSeed(long seed) {
    532         /*
    533          * Ignore call from super constructor (as well as any other calls
    534          * unfortunate enough to be passing 0).  It's critical that we
    535          * ignore call from superclass constructor, as digest has not
    536          * yet been initialized at that point.
    537          */
    538         if (seed != 0) {
    539             secureRandomSpi.engineSetSeed(longToByteArray(seed));
    540         }
    541     }
    542 
    543     /**
    544      * Generates a user-specified number of random bytes.
    545      *
    546      * <p> If a call to {@code setSeed} had not occurred previously,
    547      * the first call to this method forces this SecureRandom object
    548      * to seed itself.  This self-seeding will not occur if
    549      * {@code setSeed} was previously called.
    550      *
    551      * @param bytes the array to be filled in with random bytes.
    552      */
    553     @Override
    554     // Android-changed: Added synchronized
    555     // This method has been synchronized at least since Cupcake, so it would probably
    556     // lead to problems if it was removed.
    557     synchronized public void nextBytes(byte[] bytes) {
    558         secureRandomSpi.engineNextBytes(bytes);
    559     }
    560 
    561     /**
    562      * Generates an integer containing the user-specified number of
    563      * pseudo-random bits (right justified, with leading zeros).  This
    564      * method overrides a {@code java.util.Random} method, and serves
    565      * to provide a source of random bits to all of the methods inherited
    566      * from that class (for example, {@code nextInt},
    567      * {@code nextLong}, and {@code nextFloat}).
    568      *
    569      * @param numBits number of pseudo-random bits to be generated, where
    570      * {@code 0 <= numBits <= 32}.
    571      *
    572      * @return an {@code int} containing the user-specified number
    573      * of pseudo-random bits (right justified, with leading zeros).
    574      */
    575     @Override
    576     final protected int next(int numBits) {
    577         int numBytes = (numBits+7)/8;
    578         byte b[] = new byte[numBytes];
    579         int next = 0;
    580 
    581         nextBytes(b);
    582         for (int i = 0; i < numBytes; i++) {
    583             next = (next << 8) + (b[i] & 0xFF);
    584         }
    585 
    586         return next >>> (numBytes*8 - numBits);
    587     }
    588 
    589     /**
    590      * Returns the given number of seed bytes, computed using the seed
    591      * generation algorithm that this class uses to seed itself.  This
    592      * call may be used to seed other random number generators.
    593      *
    594      * <p>This method is only included for backwards compatibility.
    595      * The caller is encouraged to use one of the alternative
    596      * {@code getInstance} methods to obtain a SecureRandom object, and
    597      * then call the {@code generateSeed} method to obtain seed bytes
    598      * from that object.
    599      *
    600      * @param numBytes the number of seed bytes to generate.
    601      *
    602      * @return the seed bytes.
    603      *
    604      * @see #setSeed
    605      */
    606     public static byte[] getSeed(int numBytes) {
    607         if (seedGenerator == null) {
    608             seedGenerator = new SecureRandom();
    609         }
    610         return seedGenerator.generateSeed(numBytes);
    611     }
    612 
    613     /**
    614      * Returns the given number of seed bytes, computed using the seed
    615      * generation algorithm that this class uses to seed itself.  This
    616      * call may be used to seed other random number generators.
    617      *
    618      * @param numBytes the number of seed bytes to generate.
    619      *
    620      * @return the seed bytes.
    621      */
    622     public byte[] generateSeed(int numBytes) {
    623         return secureRandomSpi.engineGenerateSeed(numBytes);
    624     }
    625 
    626     /**
    627      * Helper function to convert a long into a byte array (least significant
    628      * byte first).
    629      */
    630     private static byte[] longToByteArray(long l) {
    631         byte[] retVal = new byte[8];
    632 
    633         for (int i = 0; i < 8; i++) {
    634             retVal[i] = (byte) l;
    635             l >>= 8;
    636         }
    637 
    638         return retVal;
    639     }
    640 
    641     /**
    642      * Gets a default PRNG algorithm by looking through all registered
    643      * providers. Returns the first PRNG algorithm of the first provider that
    644      * has registered a SecureRandom implementation, or null if none of the
    645      * registered providers supplies a SecureRandom implementation.
    646      */
    647     private static String getPrngAlgorithm() {
    648         for (Provider p : Providers.getProviderList().providers()) {
    649             for (Service s : p.getServices()) {
    650                 if (s.getType().equals("SecureRandom")) {
    651                     return s.getAlgorithm();
    652                 }
    653             }
    654         }
    655         return null;
    656     }
    657 
    658     /*
    659      * Lazily initialize since Pattern.compile() is heavy.
    660      * Effective Java (2nd Edition), Item 71.
    661      */
    662     private static final class StrongPatternHolder {
    663         /*
    664          * Entries are alg:prov separated by ,
    665          * Allow for prepended/appended whitespace between entries.
    666          *
    667          * Capture groups:
    668          *     1 - alg
    669          *     2 - :prov (optional)
    670          *     3 - prov (optional)
    671          *     4 - ,nextEntry (optional)
    672          *     5 - nextEntry (optional)
    673          */
    674         private static Pattern pattern =
    675             Pattern.compile(
    676                 "\\s*([\\S&&[^:,]]*)(\\:([\\S&&[^,]]*))?\\s*(\\,(.*))?");
    677     }
    678 
    679     /**
    680      * Returns a {@code SecureRandom} object.
    681      *
    682      * In Android this is equivalent to get a SHA1PRNG from OpenSSLProvider.
    683      *
    684      * Some situations require strong random values, such as when
    685      * creating high-value/long-lived secrets like RSA public/private
    686      * keys.  To help guide applications in selecting a suitable strong
    687      * {@code SecureRandom} implementation, Java distributions
    688      * include a list of known strong {@code SecureRandom}
    689      * implementations in the {@code securerandom.strongAlgorithms}
    690      * Security property.
    691      * <p>
    692      * Every implementation of the Java platform is required to
    693      * support at least one strong {@code SecureRandom} implementation.
    694      *
    695      * @return a strong {@code SecureRandom} implementation
    696      *
    697      * @throws NoSuchAlgorithmException if no algorithm is available
    698      *
    699      * @see Security#getProperty(String)
    700      *
    701      * @since 1.8
    702      */
    703     public static SecureRandom getInstanceStrong()
    704             throws NoSuchAlgorithmException {
    705 
    706         String property = AccessController.doPrivileged(
    707             new PrivilegedAction<String>() {
    708                 @Override
    709                 public String run() {
    710                     return Security.getProperty(
    711                         "securerandom.strongAlgorithms");
    712                 }
    713             });
    714 
    715         if ((property == null) || (property.length() == 0)) {
    716             throw new NoSuchAlgorithmException(
    717                 "Null/empty securerandom.strongAlgorithms Security Property");
    718         }
    719 
    720         String remainder = property;
    721         while (remainder != null) {
    722             Matcher m;
    723             if ((m = StrongPatternHolder.pattern.matcher(
    724                     remainder)).matches()) {
    725 
    726                 String alg = m.group(1);
    727                 String prov = m.group(3);
    728 
    729                 try {
    730                     if (prov == null) {
    731                         return SecureRandom.getInstance(alg);
    732                     } else {
    733                         return SecureRandom.getInstance(alg, prov);
    734                     }
    735                 } catch (NoSuchAlgorithmException |
    736                         NoSuchProviderException e) {
    737                 }
    738                 remainder = m.group(5);
    739             } else {
    740                 remainder = null;
    741             }
    742         }
    743 
    744         throw new NoSuchAlgorithmException(
    745             "No strong SecureRandom impls available: " + property);
    746     }
    747 
    748     // Declare serialVersionUID to be compatible with JDK1.1
    749     static final long serialVersionUID = 4940670005562187L;
    750 
    751     // Retain unused values serialized from JDK1.1
    752     /**
    753      * @serial
    754      */
    755     private byte[] state;
    756     /**
    757      * @serial
    758      */
    759     private MessageDigest digest = null;
    760     /**
    761      * @serial
    762      *
    763      * We know that the MessageDigest class does not implement
    764      * java.io.Serializable.  However, since this field is no longer
    765      * used, it will always be NULL and won't affect the serialization
    766      * of the SecureRandom class itself.
    767      */
    768     private byte[] randomBytes;
    769     /**
    770      * @serial
    771      */
    772     private int randomBytesUsed;
    773     /**
    774      * @serial
    775      */
    776     private long counter;
    777 }
    778