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

Save This Page
Home » openjdk-7 » java » security » [javadoc | source]