• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}/../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      */
SecureRandom()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}/../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      */
SecureRandom(byte seed[])198     public SecureRandom(byte seed[]) {
199         super(0);
200         getDefaultPRNG(true, seed);
201     }
202 
getDefaultPRNG(boolean setSeed, byte[] seed)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      */
SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)237     protected SecureRandom(SecureRandomSpi secureRandomSpi,
238                            Provider provider) {
239         this(secureRandomSpi, provider, null);
240     }
241 
SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider, String algorithm)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: this debugging mechanism is not supported in Android.
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}/../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      */
getInstance(String algorithm)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     /**
304      * Returns a SecureRandom object that implements the specified
305      * Random Number Generator (RNG) algorithm.
306      *
307      * <p> A new SecureRandom object encapsulating the
308      * SecureRandomSpi implementation from the specified provider
309      * is returned.  The specified provider must be registered
310      * in the security provider list.
311      *
312      * <p> Note that the list of registered providers may be retrieved via
313      * the {@link Security#getProviders() Security.getProviders()} method.
314      *
315      * <p> The returned SecureRandom object has not been seeded.  To seed the
316      * returned object, call the {@code setSeed} method.
317      * If {@code setSeed} is not called, the first call to
318      * {@code nextBytes} will force the SecureRandom object to seed itself.
319      * This self-seeding will not occur if {@code setSeed} was
320      * previously called.
321      *
322      * @param algorithm the name of the RNG algorithm.
323      * See the SecureRandom section in the <a href=
324      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
325      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
326      * for information about standard RNG algorithm names.
327      *
328      * @param provider the name of the provider.
329      *
330      * @return the new SecureRandom object.
331      *
332      * @exception NoSuchAlgorithmException if a SecureRandomSpi
333      *          implementation for the specified algorithm is not
334      *          available from the specified provider.
335      *
336      * @exception NoSuchProviderException if the specified provider is not
337      *          registered in the security provider list.
338      *
339      * @exception IllegalArgumentException if the provider name is null
340      *          or empty.
341      *
342      * @see Provider
343      *
344      * @since 1.2
345      */
getInstance(String algorithm, String provider)346     public static SecureRandom getInstance(String algorithm, String provider)
347             throws NoSuchAlgorithmException, NoSuchProviderException {
348         Instance instance = GetInstance.getInstance("SecureRandom",
349             SecureRandomSpi.class, algorithm, provider);
350         return new SecureRandom((SecureRandomSpi)instance.impl,
351             instance.provider, algorithm);
352     }
353 
354     /**
355      * Returns a SecureRandom object that implements the specified
356      * Random Number Generator (RNG) algorithm.
357      *
358      * <p> A new SecureRandom object encapsulating the
359      * SecureRandomSpi implementation from the specified Provider
360      * object is returned.  Note that the specified Provider object
361      * does not have to be registered in the provider list.
362      *
363      * <p> The returned SecureRandom object has not been seeded.  To seed the
364      * returned object, call the {@code setSeed} method.
365      * If {@code setSeed} is not called, the first call to
366      * {@code nextBytes} will force the SecureRandom object to seed itself.
367      * This self-seeding will not occur if {@code setSeed} was
368      * previously called.
369      *
370      * @param algorithm the name of the RNG algorithm.
371      * See the SecureRandom section in the <a href=
372      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
373      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
374      * for information about standard RNG algorithm names.
375      *
376      * @param provider the provider.
377      *
378      * @return the new SecureRandom object.
379      *
380      * @exception NoSuchAlgorithmException if a SecureRandomSpi
381      *          implementation for the specified algorithm is not available
382      *          from the specified Provider object.
383      *
384      * @exception IllegalArgumentException if the specified provider is null.
385      *
386      * @see Provider
387      *
388      * @since 1.4
389      */
getInstance(String algorithm, Provider provider)390     public static SecureRandom getInstance(String algorithm,
391             Provider provider) throws NoSuchAlgorithmException {
392         Instance instance = GetInstance.getInstance("SecureRandom",
393             SecureRandomSpi.class, algorithm, provider);
394         return new SecureRandom((SecureRandomSpi)instance.impl,
395             instance.provider, algorithm);
396     }
397 
398     /**
399      * Returns the SecureRandomSpi of this SecureRandom object.
400      */
getSecureRandomSpi()401     SecureRandomSpi getSecureRandomSpi() {
402         return secureRandomSpi;
403     }
404 
405     /**
406      * Returns the provider of this SecureRandom object.
407      *
408      * @return the provider of this SecureRandom object.
409      */
getProvider()410     public final Provider getProvider() {
411         return provider;
412     }
413 
414     /**
415      * Returns the name of the algorithm implemented by this SecureRandom
416      * object.
417      *
418      * @return the name of the algorithm or {@code unknown}
419      *          if the algorithm name cannot be determined.
420      * @since 1.5
421      */
getAlgorithm()422     public String getAlgorithm() {
423         return (algorithm != null) ? algorithm : "unknown";
424     }
425 
426     /**
427      * Reseeds this random object. The given seed supplements, rather than
428      * replaces, the existing seed. Thus, repeated calls are guaranteed
429      * never to reduce randomness.
430      *
431      * @param seed the seed.
432      *
433      * @see #getSeed
434      */
setSeed(byte[] seed)435     synchronized public void setSeed(byte[] seed) {
436         secureRandomSpi.engineSetSeed(seed);
437     }
438 
439     /**
440      * Reseeds this random object, using the eight bytes contained
441      * in the given {@code long seed}. The given seed supplements,
442      * rather than replaces, the existing seed. Thus, repeated calls
443      * are guaranteed never to reduce randomness.
444      *
445      * <p>This method is defined for compatibility with
446      * {@code java.util.Random}.
447      *
448      * @param seed the seed.
449      *
450      * @see #getSeed
451      */
452     @Override
setSeed(long seed)453     public void setSeed(long seed) {
454         /*
455          * Ignore call from super constructor (as well as any other calls
456          * unfortunate enough to be passing 0).  It's critical that we
457          * ignore call from superclass constructor, as digest has not
458          * yet been initialized at that point.
459          */
460         if (seed != 0) {
461             secureRandomSpi.engineSetSeed(longToByteArray(seed));
462         }
463     }
464 
465     /**
466      * Generates a user-specified number of random bytes.
467      *
468      * <p> If a call to {@code setSeed} had not occurred previously,
469      * the first call to this method forces this SecureRandom object
470      * to seed itself.  This self-seeding will not occur if
471      * {@code setSeed} was previously called.
472      *
473      * @param bytes the array to be filled in with random bytes.
474      */
475     @Override
476     // Android-changed: Added synchronized
477     // This method has been synchronized at least since Cupcake, so it would probably
478     // lead to problems if it was removed.
nextBytes(byte[] bytes)479     synchronized public void nextBytes(byte[] bytes) {
480         secureRandomSpi.engineNextBytes(bytes);
481     }
482 
483     /**
484      * Generates an integer containing the user-specified number of
485      * pseudo-random bits (right justified, with leading zeros).  This
486      * method overrides a {@code java.util.Random} method, and serves
487      * to provide a source of random bits to all of the methods inherited
488      * from that class (for example, {@code nextInt},
489      * {@code nextLong}, and {@code nextFloat}).
490      *
491      * @param numBits number of pseudo-random bits to be generated, where
492      * {@code 0 <= numBits <= 32}.
493      *
494      * @return an {@code int} containing the user-specified number
495      * of pseudo-random bits (right justified, with leading zeros).
496      */
497     @Override
next(int numBits)498     final protected int next(int numBits) {
499         int numBytes = (numBits+7)/8;
500         byte b[] = new byte[numBytes];
501         int next = 0;
502 
503         nextBytes(b);
504         for (int i = 0; i < numBytes; i++) {
505             next = (next << 8) + (b[i] & 0xFF);
506         }
507 
508         return next >>> (numBytes*8 - numBits);
509     }
510 
511     /**
512      * Returns the given number of seed bytes, computed using the seed
513      * generation algorithm that this class uses to seed itself.  This
514      * call may be used to seed other random number generators.
515      *
516      * <p>This method is only included for backwards compatibility.
517      * The caller is encouraged to use one of the alternative
518      * {@code getInstance} methods to obtain a SecureRandom object, and
519      * then call the {@code generateSeed} method to obtain seed bytes
520      * from that object.
521      *
522      * @param numBytes the number of seed bytes to generate.
523      *
524      * @return the seed bytes.
525      *
526      * @see #setSeed
527      */
getSeed(int numBytes)528     public static byte[] getSeed(int numBytes) {
529         if (seedGenerator == null) {
530             seedGenerator = new SecureRandom();
531         }
532         return seedGenerator.generateSeed(numBytes);
533     }
534 
535     /**
536      * Returns the given number of seed bytes, computed using the seed
537      * generation algorithm that this class uses to seed itself.  This
538      * call may be used to seed other random number generators.
539      *
540      * @param numBytes the number of seed bytes to generate.
541      *
542      * @return the seed bytes.
543      */
generateSeed(int numBytes)544     public byte[] generateSeed(int numBytes) {
545         return secureRandomSpi.engineGenerateSeed(numBytes);
546     }
547 
548     /**
549      * Helper function to convert a long into a byte array (least significant
550      * byte first).
551      */
longToByteArray(long l)552     private static byte[] longToByteArray(long l) {
553         byte[] retVal = new byte[8];
554 
555         for (int i = 0; i < 8; i++) {
556             retVal[i] = (byte) l;
557             l >>= 8;
558         }
559 
560         return retVal;
561     }
562 
563     /**
564      * Gets a default PRNG algorithm by looking through all registered
565      * providers. Returns the first PRNG algorithm of the first provider that
566      * has registered a SecureRandom implementation, or null if none of the
567      * registered providers supplies a SecureRandom implementation.
568      */
getPrngAlgorithm()569     private static String getPrngAlgorithm() {
570         for (Provider p : Providers.getProviderList().providers()) {
571             for (Service s : p.getServices()) {
572                 if (s.getType().equals("SecureRandom")) {
573                     return s.getAlgorithm();
574                 }
575             }
576         }
577         return null;
578     }
579 
580     /*
581      * Lazily initialize since Pattern.compile() is heavy.
582      * Effective Java (2nd Edition), Item 71.
583      */
584     private static final class StrongPatternHolder {
585         /*
586          * Entries are alg:prov separated by ,
587          * Allow for prepended/appended whitespace between entries.
588          *
589          * Capture groups:
590          *     1 - alg
591          *     2 - :prov (optional)
592          *     3 - prov (optional)
593          *     4 - ,nextEntry (optional)
594          *     5 - nextEntry (optional)
595          */
596         private static Pattern pattern =
597             Pattern.compile(
598                 "\\s*([\\S&&[^:,]]*)(\\:([\\S&&[^,]]*))?\\s*(\\,(.*))?");
599     }
600 
601     /**
602      * Returns a {@code SecureRandom} object.
603      *
604      * In Android this is equivalent to get a SHA1PRNG from AndroidOpenSSL.
605      *
606      * Some situations require strong random values, such as when
607      * creating high-value/long-lived secrets like RSA public/private
608      * keys.  To help guide applications in selecting a suitable strong
609      * {@code SecureRandom} implementation, Java distributions
610      * include a list of known strong {@code SecureRandom}
611      * implementations in the {@code securerandom.strongAlgorithms}
612      * Security property.
613      * <p>
614      * Every implementation of the Java platform is required to
615      * support at least one strong {@code SecureRandom} implementation.
616      *
617      * @return a strong {@code SecureRandom} implementation
618      *
619      * @throws NoSuchAlgorithmException if no algorithm is available
620      *
621      * @see Security#getProperty(String)
622      *
623      * @since 1.8
624      */
getInstanceStrong()625     public static SecureRandom getInstanceStrong()
626             throws NoSuchAlgorithmException {
627 
628         String property = AccessController.doPrivileged(
629             new PrivilegedAction<String>() {
630                 @Override
631                 public String run() {
632                     return Security.getProperty(
633                         "securerandom.strongAlgorithms");
634                 }
635             });
636 
637         if ((property == null) || (property.length() == 0)) {
638             throw new NoSuchAlgorithmException(
639                 "Null/empty securerandom.strongAlgorithms Security Property");
640         }
641 
642         String remainder = property;
643         while (remainder != null) {
644             Matcher m;
645             if ((m = StrongPatternHolder.pattern.matcher(
646                     remainder)).matches()) {
647 
648                 String alg = m.group(1);
649                 String prov = m.group(3);
650 
651                 try {
652                     if (prov == null) {
653                         return SecureRandom.getInstance(alg);
654                     } else {
655                         return SecureRandom.getInstance(alg, prov);
656                     }
657                 } catch (NoSuchAlgorithmException |
658                         NoSuchProviderException e) {
659                 }
660                 remainder = m.group(5);
661             } else {
662                 remainder = null;
663             }
664         }
665 
666         throw new NoSuchAlgorithmException(
667             "No strong SecureRandom impls available: " + property);
668     }
669 
670     // Declare serialVersionUID to be compatible with JDK1.1
671     static final long serialVersionUID = 4940670005562187L;
672 
673     // Retain unused values serialized from JDK1.1
674     /**
675      * @serial
676      */
677     private byte[] state;
678     /**
679      * @serial
680      */
681     private MessageDigest digest = null;
682     /**
683      * @serial
684      *
685      * We know that the MessageDigest class does not implement
686      * java.io.Serializable.  However, since this field is no longer
687      * used, it will always be NULL and won't affect the serialization
688      * of the SecureRandom class itself.
689      */
690     private byte[] randomBytes;
691     /**
692      * @serial
693      */
694     private int randomBytesUsed;
695     /**
696      * @serial
697      */
698     private long counter;
699 }
700