Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4422561

Faulty implementation of SecureRandom default constructor

XMLWordPrintable

    • beta
    • generic
    • generic



      Name: krC82822 Date: 03/06/2001


      6 Mar 2001, eval1127@eng -- see also: #'s, 4405056, 4219386.
      This may be a dupe/relative of # 4405056.
      ---------------
      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
      Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)

      The bug is a result of the implementation of the static getPrngAlgorithm()
      method in java.security.SecureRandom. This operation is called as a result of
      constructing a SecureRandom instance directly rather than through the
      getInstance() operation.

      The error occurs when a new provider is used that provides a new SecureRandom
      implementation.

      The offending code is shown below.
        /**
           * Gets a default PRNG algorithm by looking through all registered
           * providers. Returns the first PRNG algorithm of the first provider that
           * has registered a SecureRandom implementation, or null if none of the
           * registered providers supplies a SecureRandom implementation.
           */
          private static String getPrngAlgorithm() {
              Provider[] provs = Security.getProviders();
              for (int i=0; i<provs.length; i++) {
                  // search the provider's properties list for a property name
                  // that starts with "SecureRandom."
                  for (Enumeration e = provs[i].propertyNames();
                       e.hasMoreElements();) {
                      String propName = (String)e.nextElement();
                      if (propName.startsWith("SecureRandom.")) {
                          int index = propName.indexOf(".", 0);
                          return propName.substring(index+1);
                      }
                  }
              }
              return null;
          }

      The Sun provider adds two entries in the provider instance. These are as
      follows,

            public Object run()
            {
              ....
              put("SecureRandom.SHA1PRNG", "sun.security.provider.SecureRandom");
              ....
              put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
              ....
              return null;
            }

      This means that the getPrngAlgorithm function is dependent on the actual
      ordering of entries with the Hashtable.

      If a different set of provider entries is used in this case only two entries,
      corrsponding to the entries illustrated above but with differing implementations
      Then the ordering of the entries in the enumeration may be different.

      For example the getPrngAlgorithm() operation returned an algorithm string
      'SHA1PRNG ImplementedIn'. This will obviously cause the call to getInstance() in
      the SecureRandom(byte[] seed) constructor to fail.

      The second coding error is the erroneous assumption that the
      NoSuchAlgorithmException will never be thrown from the call to getInstance(). In
      the situation described here the exception will indeed be thrown and the error
      will cause a NullPointerException to be thrown when nextLong() of similar
      operations are called.

      The offending code fragment is below,

          public SecureRandom(byte seed[]) {
              super(0);
              String prng = getPrngAlgorithm();
              if (prng == null) {
                  // bummer, get the SUN implementation
                  this.secureRandomSpi = new sun.security.provider.SecureRandom();
                  this.provider = new sun.security.provider.Sun();
                  this.secureRandomSpi.engineSetSeed(seed);
              } else {
                  try {
                      SecureRandom random = getInstance(prng);
                      this.secureRandomSpi = random.getSecureRandomSpi();
                      this.provider = random.getProvider();
                      this.secureRandomSpi.engineSetSeed(seed);
                  } catch (NoSuchAlgorithmException nsae) {
                      // never happens, because we made sure the algorithm exists
                  }
              }
          }


      The most sensible solution would be to move to the situation where SecureRandom
      did not derive from java.util.Random and adhered to the design contracts of the
      JCA and JCE.


      The problem is compounded by the fact that a much third party software has
      implement code that uses the SecureRandom constructor making it difficult to
      plugin new crypto providers.
      (Review ID: 116890)
      ======================================================================

            smalkanisunw Seema Malkani (Inactive)
            kryansunw Kevin Ryan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: