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 
  33 import sun.security.jca.*;
  34 import sun.security.jca.GetInstance.Instance;
  35 
  36 /**
  37  * This class provides a cryptographically strong random number
  38  * generator (RNG).
  39  *
  40  * <p>A cryptographically strong random number
  41  * minimally complies with the statistical random number generator tests
  42  * specified in <a href="http://csrc.nist.gov/cryptval/140-2.htm">
  43  * <i>FIPS 140-2, Security Requirements for Cryptographic Modules</i></a>,
  44  * section 4.9.1.
  45  * Additionally, SecureRandom must produce non-deterministic output.
  46  * Therefore any seed material passed to a SecureRandom object must be
  47  * unpredictable, and all SecureRandom output sequences must be
  48  * cryptographically strong, as described in
  49  * <a href="http://www.ietf.org/rfc/rfc1750.txt">
  50  * <i>RFC 1750: Randomness Recommendations for Security</i></a>.
  51  *
  52  * <p>A caller obtains a SecureRandom instance via the
  53  * no-argument constructor or one of the {@code getInstance} methods:
  54  *
  55  * <pre>
  56  *      SecureRandom random = new SecureRandom();
  57  * </pre>
  58  *
  59  * <p> Many SecureRandom implementations are in the form of a pseudo-random
  60  * number generator (PRNG), which means they use a deterministic algorithm
  61  * to produce a pseudo-random sequence from a true random seed.
  62  * Other implementations may produce true random numbers,
  63  * and yet others may use a combination of both techniques.
  64  *
  65  * <p> Typical callers of SecureRandom invoke the following methods
  66  * to retrieve random bytes:
  67  *
  68  * <pre>
  69  *      SecureRandom random = new SecureRandom();
  70  *      byte bytes[] = new byte[20];
  71  *      random.nextBytes(bytes);
  72  * </pre>
  73  *
  74  * <p> Callers may also invoke the {@code generateSeed} method
  75  * to generate a given number of seed bytes (to seed other random number
  76  * generators, for example):
  77  * <pre>
  78  *      byte seed[] = random.generateSeed(20);
  79  * </pre>
  80  *
  81  * Note: Depending on the implementation, the {@code generateSeed} and
  82  * {@code nextBytes} methods may block as entropy is being gathered,
  83  * for example, if they need to read from /dev/random on various Unix-like
  84  * operating systems.
  85  *
  86  * @see java.security.SecureRandomSpi
  87  * @see java.util.Random
  88  *
  89  * @author Benjamin Renaud
  90  * @author Josh Bloch
  91  */
  92 
  93 public class SecureRandom extends java.util.Random {
  94 
  95     /**
  96      * The provider.
  97      *
  98      * @serial
  99      * @since 1.2
 100      */
 101     private Provider provider = null;
 102 
 103     /**
 104      * The provider implementation.
 105      *
 106      * @serial
 107      * @since 1.2
 108      */
 109     private SecureRandomSpi secureRandomSpi = null;
 110 
 111     /*
 112      * The algorithm name of null if unknown.
 113      *
 114      * @serial
 115      * @since 1.5
 116      */
 117     private String algorithm;
 118 
 119     // Seed Generator
 120     private static volatile SecureRandom seedGenerator = null;
 121 
 122     /**
 123      * Constructs a secure random number generator (RNG) implementing the
 124      * default random number algorithm.
 125      *
 126      * <p> This constructor traverses the list of registered security Providers,
 127      * starting with the most preferred Provider.
 128      * A new SecureRandom object encapsulating the
 129      * SecureRandomSpi implementation from the first
 130      * Provider that supports a SecureRandom (RNG) algorithm is returned.
 131      * If none of the Providers support a RNG algorithm,
 132      * then an implementation-specific default is returned.
 133      *
 134      * <p> Note that the list of registered providers may be retrieved via
 135      * the {@link Security#getProviders() Security.getProviders()} method.
 136      *
 137      * <p> See the SecureRandom section in the <a href=
 138      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
 139      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 140      * for information about standard RNG algorithm names.
 141      *
 142      * <p> The returned SecureRandom object has not been seeded.  To seed the
 143      * returned object, call the {@code setSeed} method.
 144      * If {@code setSeed} is not called, the first call to
 145      * {@code nextBytes} will force the SecureRandom object to seed itself.
 146      * This self-seeding will not occur if {@code setSeed} was
 147      * previously called.
 148      */
 149     public SecureRandom() {
 150         /*
 151          * This call to our superclass constructor will result in a call
 152          * to our own {@code setSeed} method, which will return
 153          * immediately when it is passed zero.
 154          */
 155         super(0);
 156         getDefaultPRNG(false, null);
 157     }
 158 
 159     /**
 160      * Constructs a secure random number generator (RNG) implementing the
 161      * default random number algorithm.
 162      * The SecureRandom instance is seeded with the specified seed bytes.
 163      *
 164      * <p> This constructor traverses the list of registered security Providers,
 165      * starting with the most preferred Provider.
 166      * A new SecureRandom object encapsulating the
 167      * SecureRandomSpi implementation from the first
 168      * Provider that supports a SecureRandom (RNG) algorithm is returned.
 169      * If none of the Providers support a RNG algorithm,
 170      * then an implementation-specific default is returned.
 171      *
 172      * <p> Note that the list of registered providers may be retrieved via
 173      * the {@link Security#getProviders() Security.getProviders()} method.
 174      *
 175      * <p> See the SecureRandom section in the <a href=
 176      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
 177      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 178      * for information about standard RNG algorithm names.
 179      *
 180      * @param seed the seed.
 181      */
 182     public SecureRandom(byte seed[]) {
 183         super(0);
 184         getDefaultPRNG(true, seed);
 185     }
 186 
 187     private void getDefaultPRNG(boolean setSeed, byte[] seed) {
 188         String prng = getPrngAlgorithm();
 189         if (prng == null) {
 190             // bummer, get the SUN implementation
 191             prng = "SHA1PRNG";
 192             this.secureRandomSpi = new sun.security.provider.SecureRandom();
 193             this.provider = Providers.getSunProvider();
 194             if (setSeed) {
 195                 this.secureRandomSpi.engineSetSeed(seed);
 196             }
 197         } else {
 198             try {
 199                 SecureRandom random = SecureRandom.getInstance(prng);
 200                 this.secureRandomSpi = random.getSecureRandomSpi();
 201                 this.provider = random.getProvider();
 202                 if (setSeed) {
 203                     this.secureRandomSpi.engineSetSeed(seed);
 204                 }
 205             } catch (NoSuchAlgorithmException nsae) {
 206                 // never happens, because we made sure the algorithm exists
 207                 throw new RuntimeException(nsae);
 208             }
 209         }
 210         // JDK 1.1 based implementations subclass SecureRandom instead of
 211         // SecureRandomSpi. They will also go through this code path because
 212         // they must call a SecureRandom constructor as it is their superclass.
 213         // If we are dealing with such an implementation, do not set the
 214         // algorithm value as it would be inaccurate.
 215         if (getClass() == SecureRandom.class) {
 216             this.algorithm = prng;
 217         }
 218     }
 219 
 220     /**
 221      * Creates a SecureRandom object.
 222      *
 223      * @param secureRandomSpi the SecureRandom implementation.
 224      * @param provider the provider.
 225      */
 226     protected SecureRandom(SecureRandomSpi secureRandomSpi,
 227                            Provider provider) {
 228         this(secureRandomSpi, provider, null);
 229     }
 230 
 231     private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider,
 232             String algorithm) {
 233         super(0);
 234         this.secureRandomSpi = secureRandomSpi;
 235         this.provider = provider;
 236         this.algorithm = algorithm;
 237     }
 238 
 239     /**
 240      * Returns a SecureRandom object that implements the specified
 241      * Random Number Generator (RNG) algorithm.
 242      *
 243      * <p> This method traverses the list of registered security Providers,
 244      * starting with the most preferred Provider.
 245      * A new SecureRandom object encapsulating the
 246      * SecureRandomSpi implementation from the first
 247      * Provider that supports the specified algorithm is returned.
 248      *
 249      * <p> Note that the list of registered providers may be retrieved via
 250      * the {@link Security#getProviders() Security.getProviders()} method.
 251      *
 252      * <p> The returned SecureRandom object has not been seeded.  To seed the
 253      * returned object, call the {@code setSeed} method.
 254      * If {@code setSeed} is not called, the first call to
 255      * {@code nextBytes} will force the SecureRandom object to seed itself.
 256      * This self-seeding will not occur if {@code setSeed} was
 257      * previously called.
 258      *
 259      * @param algorithm the name of the RNG algorithm.
 260      * See the SecureRandom section in the <a href=
 261      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
 262      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 263      * for information about standard RNG algorithm names.
 264      *
 265      * @return the new SecureRandom object.
 266      *
 267      * @exception NoSuchAlgorithmException if no Provider supports a
 268      *          SecureRandomSpi implementation for the
 269      *          specified algorithm.
 270      *
 271      * @see Provider
 272      *
 273      * @since 1.2
 274      */
 275     public static SecureRandom getInstance(String algorithm)
 276             throws NoSuchAlgorithmException {
 277         Instance instance = GetInstance.getInstance("SecureRandom",
 278             SecureRandomSpi.class, algorithm);
 279         return new SecureRandom((SecureRandomSpi)instance.impl,
 280             instance.provider, algorithm);
 281     }
 282 
 283     /**
 284      * Returns a SecureRandom object that implements the specified
 285      * Random Number Generator (RNG) algorithm.
 286      *
 287      * <p> A new SecureRandom object encapsulating the
 288      * SecureRandomSpi implementation from the specified provider
 289      * is returned.  The specified provider must be registered
 290      * in the security provider list.
 291      *
 292      * <p> Note that the list of registered providers may be retrieved via
 293      * the {@link Security#getProviders() Security.getProviders()} method.
 294      *
 295      * <p> The returned SecureRandom object has not been seeded.  To seed the
 296      * returned object, call the {@code setSeed} method.
 297      * If {@code setSeed} is not called, the first call to
 298      * {@code nextBytes} will force the SecureRandom object to seed itself.
 299      * This self-seeding will not occur if {@code setSeed} was
 300      * previously called.
 301      *
 302      * @param algorithm the name of the RNG algorithm.
 303      * See the SecureRandom section in the <a href=
 304      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
 305      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 306      * for information about standard RNG algorithm names.
 307      *
 308      * @param provider the name of the provider.
 309      *
 310      * @return the new SecureRandom object.
 311      *
 312      * @exception NoSuchAlgorithmException if a SecureRandomSpi
 313      *          implementation for the specified algorithm is not
 314      *          available from the specified provider.
 315      *
 316      * @exception NoSuchProviderException if the specified provider is not
 317      *          registered in the security provider list.
 318      *
 319      * @exception IllegalArgumentException if the provider name is null
 320      *          or empty.
 321      *
 322      * @see Provider
 323      *
 324      * @since 1.2
 325      */
 326     public static SecureRandom getInstance(String algorithm, String provider)
 327             throws NoSuchAlgorithmException, NoSuchProviderException {
 328         Instance instance = GetInstance.getInstance("SecureRandom",
 329             SecureRandomSpi.class, algorithm, provider);
 330         return new SecureRandom((SecureRandomSpi)instance.impl,
 331             instance.provider, algorithm);
 332     }
 333 
 334     /**
 335      * Returns a SecureRandom object that implements the specified
 336      * Random Number Generator (RNG) algorithm.
 337      *
 338      * <p> A new SecureRandom object encapsulating the
 339      * SecureRandomSpi implementation from the specified Provider
 340      * object is returned.  Note that the specified Provider object
 341      * does not have to be registered in the provider list.
 342      *
 343      * <p> The returned SecureRandom object has not been seeded.  To seed the
 344      * returned object, call the {@code setSeed} method.
 345      * If {@code setSeed} is not called, the first call to
 346      * {@code nextBytes} will force the SecureRandom object to seed itself.
 347      * This self-seeding will not occur if {@code setSeed} was
 348      * previously called.
 349      *
 350      * @param algorithm the name of the RNG algorithm.
 351      * See the SecureRandom section in the <a href=
 352      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
 353      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 354      * for information about standard RNG algorithm names.
 355      *
 356      * @param provider the provider.
 357      *
 358      * @return the new SecureRandom object.
 359      *
 360      * @exception NoSuchAlgorithmException if a SecureRandomSpi
 361      *          implementation for the specified algorithm is not available
 362      *          from the specified Provider object.
 363      *
 364      * @exception IllegalArgumentException if the specified provider is null.
 365      *
 366      * @see Provider
 367      *
 368      * @since 1.4
 369      */
 370     public static SecureRandom getInstance(String algorithm,
 371             Provider provider) throws NoSuchAlgorithmException {
 372         Instance instance = GetInstance.getInstance("SecureRandom",
 373             SecureRandomSpi.class, algorithm, provider);
 374         return new SecureRandom((SecureRandomSpi)instance.impl,
 375             instance.provider, algorithm);
 376     }
 377 
 378     /**
 379      * Returns the SecureRandomSpi of this SecureRandom object.
 380      */
 381     SecureRandomSpi getSecureRandomSpi() {
 382         return secureRandomSpi;
 383     }
 384 
 385     /**
 386      * Returns the provider of this SecureRandom object.
 387      *
 388      * @return the provider of this SecureRandom object.
 389      */
 390     public final Provider getProvider() {
 391         return provider;
 392     }
 393 
 394     /**
 395      * Returns the name of the algorithm implemented by this SecureRandom
 396      * object.
 397      *
 398      * @return the name of the algorithm or {@code unknown}
 399      *          if the algorithm name cannot be determined.
 400      * @since 1.5
 401      */
 402     public String getAlgorithm() {
 403         return (algorithm != null) ? algorithm : "unknown";
 404     }
 405 
 406     /**
 407      * Reseeds this random object. The given seed supplements, rather than
 408      * replaces, the existing seed. Thus, repeated calls are guaranteed
 409      * never to reduce randomness.
 410      *
 411      * @param seed the seed.
 412      *
 413      * @see #getSeed
 414      */
 415     synchronized public void setSeed(byte[] seed) {
 416         secureRandomSpi.engineSetSeed(seed);
 417     }
 418 
 419     /**
 420      * Reseeds this random object, using the eight bytes contained
 421      * in the given {@code long seed}. The given seed supplements,
 422      * rather than replaces, the existing seed. Thus, repeated calls
 423      * are guaranteed never to reduce randomness.
 424      *
 425      * <p>This method is defined for compatibility with
 426      * {@code java.util.Random}.
 427      *
 428      * @param seed the seed.
 429      *
 430      * @see #getSeed
 431      */
 432     @Override
 433     public void setSeed(long seed) {
 434         /*
 435          * Ignore call from super constructor (as well as any other calls
 436          * unfortunate enough to be passing 0).  It's critical that we
 437          * ignore call from superclass constructor, as digest has not
 438          * yet been initialized at that point.
 439          */
 440         if (seed != 0) {
 441             secureRandomSpi.engineSetSeed(longToByteArray(seed));
 442         }
 443     }
 444 
 445     /**
 446      * Generates a user-specified number of random bytes.
 447      *
 448      * <p> If a call to {@code setSeed} had not occurred previously,
 449      * the first call to this method forces this SecureRandom object
 450      * to seed itself.  This self-seeding will not occur if
 451      * {@code setSeed} was previously called.
 452      *
 453      * @param bytes the array to be filled in with random bytes.
 454      */
 455     @Override
 456     synchronized public void nextBytes(byte[] bytes) {
 457         secureRandomSpi.engineNextBytes(bytes);
 458     }
 459 
 460     /**
 461      * Generates an integer containing the user-specified number of
 462      * pseudo-random bits (right justified, with leading zeros).  This
 463      * method overrides a {@code java.util.Random} method, and serves
 464      * to provide a source of random bits to all of the methods inherited
 465      * from that class (for example, {@code nextInt},
 466      * {@code nextLong}, and {@code nextFloat}).
 467      *
 468      * @param numBits number of pseudo-random bits to be generated, where
 469      * {@code 0 <= numBits <= 32}.
 470      *
 471      * @return an {@code int} containing the user-specified number
 472      * of pseudo-random bits (right justified, with leading zeros).
 473      */
 474     @Override
 475     final protected int next(int numBits) {
 476         int numBytes = (numBits+7)/8;
 477         byte b[] = new byte[numBytes];
 478         int next = 0;
 479 
 480         nextBytes(b);
 481         for (int i = 0; i < numBytes; i++) {
 482             next = (next << 8) + (b[i] & 0xFF);
 483         }
 484 
 485         return next >>> (numBytes*8 - numBits);
 486     }
 487 
 488     /**
 489      * Returns the given number of seed bytes, computed using the seed
 490      * generation algorithm that this class uses to seed itself.  This
 491      * call may be used to seed other random number generators.
 492      *
 493      * <p>This method is only included for backwards compatibility.
 494      * The caller is encouraged to use one of the alternative
 495      * {@code getInstance} methods to obtain a SecureRandom object, and
 496      * then call the {@code generateSeed} method to obtain seed bytes
 497      * from that object.
 498      *
 499      * @param numBytes the number of seed bytes to generate.
 500      *
 501      * @return the seed bytes.
 502      *
 503      * @see #setSeed
 504      */
 505     public static byte[] getSeed(int numBytes) {
 506         if (seedGenerator == null) {
 507             seedGenerator = new SecureRandom();
 508         }
 509         return seedGenerator.generateSeed(numBytes);
 510     }
 511 
 512     /**
 513      * Returns the given number of seed bytes, computed using the seed
 514      * generation algorithm that this class uses to seed itself.  This
 515      * call may be used to seed other random number generators.
 516      *
 517      * @param numBytes the number of seed bytes to generate.
 518      *
 519      * @return the seed bytes.
 520      */
 521     public byte[] generateSeed(int numBytes) {
 522         return secureRandomSpi.engineGenerateSeed(numBytes);
 523     }
 524 
 525     /**
 526      * Helper function to convert a long into a byte array (least significant
 527      * byte first).
 528      */
 529     private static byte[] longToByteArray(long l) {
 530         byte[] retVal = new byte[8];
 531 
 532         for (int i = 0; i < 8; i++) {
 533             retVal[i] = (byte) l;
 534             l >>= 8;
 535         }
 536 
 537         return retVal;
 538     }
 539 
 540     /**
 541      * Gets a default PRNG algorithm by looking through all registered
 542      * providers. Returns the first PRNG algorithm of the first provider that
 543      * has registered a SecureRandom implementation, or null if none of the
 544      * registered providers supplies a SecureRandom implementation.
 545      */
 546     private static String getPrngAlgorithm() {
 547         for (Provider p : Providers.getProviderList().providers()) {
 548             for (Service s : p.getServices()) {
 549                 if (s.getType().equals("SecureRandom")) {
 550                     return s.getAlgorithm();
 551                 }
 552             }
 553         }
 554         return null;
 555     }
 556 
 557     /*
 558      * Lazily initialize since Pattern.compile() is heavy.
 559      * Effective Java (2nd Edition), Item 71.
 560      */
 561     private static final class StrongPatternHolder {
 562         /*
 563          * Entries are alg:prov separated by ,
 564          * Allow for prepended/appended whitespace between entries.
 565          *
 566          * Capture groups:
 567          *     1 - alg
 568          *     2 - :prov (optional)
 569          *     3 - prov (optional)
 570          *     4 - ,nextEntry (optional)
 571          *     5 - nextEntry (optional)
 572          */
 573         private static Pattern pattern =
 574             Pattern.compile(
 575                 "\\s*([\\S&&[^:,]]*)(\\:([\\S&&[^,]]*))?\\s*(\\,(.*))?");
 576     }
 577 
 578     /**
 579      * Returns a {@code SecureRandom} object that was selected by using
 580      * the algorithms/providers specified in the {@code
 581      * securerandom.strongAlgorithms} Security property.
 582      * <p>
 583      * Some situations require strong random values, such as when
 584      * creating high-value/long-lived secrets like RSA public/private
 585      * keys.  To help guide applications in selecting a suitable strong
 586      * {@code SecureRandom} implementation, Java distributions should
 587      * include a list of known strong {@code SecureRandom}
 588      * implementations in the {@code securerandom.strongAlgorithms}
 589      * Security property.
 590      *
 591      * <pre>
 592      *     SecureRandom sr = SecureRandom.getStrongSecureRandom();
 593      *
 594      *     if (sr == null) {
 595      *         // Decide if this is a problem, and whether to recover.
 596      *         sr = new SecureRandom();
 597      *         if (!goodEnough(sr)) {
 598      *             return;
 599      *         }
 600      *     }
 601      *
 602      *     keyPairGenerator.initialize(2048, sr);
 603      * </pre>
 604      *
 605      * @return a strong {@code SecureRandom} implementation as indicated
 606      * by the {@code securerandom.strongAlgorithms} Security property, or
 607      * null if none are available.
 608      *
 609      * @see Security#getProperty(String)
 610      *
 611      * @since 1.8
 612      */
 613     public static SecureRandom getStrongSecureRandom() {
 614 
 615         String property = AccessController.doPrivileged(
 616             new PrivilegedAction<String>() {
 617                 @Override
 618                 public String run() {
 619                     return Security.getProperty(
 620                         "securerandom.strongAlgorithms");
 621                 }
 622             });
 623 
 624         if ((property == null) || (property.length() == 0)) {
 625             return null;
 626         }
 627 
 628         String remainder = property;
 629         while (remainder != null) {
 630             Matcher m;
 631             if ((m = StrongPatternHolder.pattern.matcher(
 632                     remainder)).matches()) {
 633 
 634                 String alg = m.group(1);
 635                 String prov = m.group(3);
 636 
 637                 try {
 638                     if (prov == null) {
 639                         return SecureRandom.getInstance(alg);
 640                     } else {
 641                         return SecureRandom.getInstance(alg, prov);
 642                     }
 643                 } catch (NoSuchAlgorithmException |
 644                         NoSuchProviderException e) {
 645                 }
 646                 remainder = m.group(5);
 647             } else {
 648                 remainder = null;
 649             }
 650         }
 651 
 652         return null;
 653     }
 654 
 655     // Declare serialVersionUID to be compatible with JDK1.1
 656     static final long serialVersionUID = 4940670005562187L;
 657 
 658     // Retain unused values serialized from JDK1.1
 659     /**
 660      * @serial
 661      */
 662     private byte[] state;
 663     /**
 664      * @serial
 665      */
 666     private MessageDigest digest = null;
 667     /**
 668      * @serial
 669      *
 670      * We know that the MessageDigest class does not implement
 671      * java.io.Serializable.  However, since this field is no longer
 672      * used, it will always be NULL and won't affect the serialization
 673      * of the SecureRandom class itself.
 674      */
 675     private byte[] randomBytes;
 676     /**
 677      * @serial
 678      */
 679     private int randomBytesUsed;
 680     /**
 681      * @serial
 682      */
 683     private long counter;
 684 }