Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]
    1   /*
    2    * Copyright (c) 1997, 2007, 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 com.sun.crypto.provider;
   27   
   28   import java.math.BigInteger;
   29   import java.security;
   30   import java.security.spec.AlgorithmParameterSpec;
   31   import java.security.spec.InvalidParameterSpecException;
   32   import javax.crypto.spec.DHParameterSpec;
   33   import javax.crypto.spec.DHGenParameterSpec;
   34   
   35   import sun.security.provider.ParameterCache;
   36   
   37   /**
   38    * This class represents the key pair generator for Diffie-Hellman key pairs.
   39    *
   40    * <p>This key pair generator may be initialized in two different ways:
   41    *
   42    * <ul>
   43    * <li>By providing the size in bits of the prime modulus -
   44    * This will be used to create a prime modulus and base generator, which will
   45    * then be used to create the Diffie-Hellman key pair. The default size of the
   46    * prime modulus is 1024 bits.
   47    * <li>By providing a prime modulus and base generator
   48    * </ul>
   49    *
   50    * @author Jan Luehe
   51    *
   52    *
   53    * @see java.security.KeyPairGenerator
   54    */
   55   public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
   56   
   57       // parameters to use or null if not specified
   58       private DHParameterSpec params;
   59   
   60       // The size in bits of the prime modulus
   61       private int pSize;
   62   
   63       // The size in bits of the random exponent (private value)
   64       private int lSize;
   65   
   66       // The source of randomness
   67       private SecureRandom random;
   68   
   69       public DHKeyPairGenerator() {
   70           super();
   71           initialize(1024, null);
   72       }
   73   
   74       /**
   75        * Initializes this key pair generator for a certain keysize and source of
   76        * randomness.
   77        * The keysize is specified as the size in bits of the prime modulus.
   78        *
   79        * @param keysize the keysize (size of prime modulus) in bits
   80        * @param random the source of randomness
   81        */
   82       public void initialize(int keysize, SecureRandom random) {
   83           if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) {
   84               throw new InvalidParameterException("Keysize must be multiple "
   85                                                   + "of 64, and can only range "
   86                                                   + "from 512 to 1024 "
   87                                                   + "(inclusive)");
   88           }
   89           this.pSize = keysize;
   90           this.lSize = 0;
   91           this.random = random;
   92           this.params = null;
   93       }
   94   
   95       /**
   96        * Initializes this key pair generator for the specified parameter
   97        * set and source of randomness.
   98        *
   99        * <p>The given parameter set contains the prime modulus, the base
  100        * generator, and optionally the requested size in bits of the random
  101        * exponent (private value).
  102        *
  103        * @param params the parameter set used to generate the key pair
  104        * @param random the source of randomness
  105        *
  106        * @exception InvalidAlgorithmParameterException if the given parameters
  107        * are inappropriate for this key pair generator
  108        */
  109       public void initialize(AlgorithmParameterSpec algParams,
  110               SecureRandom random) throws InvalidAlgorithmParameterException {
  111           if (!(algParams instanceof DHParameterSpec)){
  112               throw new InvalidAlgorithmParameterException
  113                   ("Inappropriate parameter type");
  114           }
  115   
  116           params = (DHParameterSpec)algParams;
  117           pSize = params.getP().bitLength();
  118           if ((pSize < 512) || (pSize > 1024) ||
  119               (pSize % 64 != 0)) {
  120               throw new InvalidAlgorithmParameterException
  121                   ("Prime size must be multiple of 64, and can only range "
  122                    + "from 512 to 1024 (inclusive)");
  123           }
  124   
  125           // exponent size is optional, could be 0
  126           lSize = params.getL();
  127   
  128           // Require exponentSize < primeSize
  129           if ((lSize != 0) && (lSize > pSize)) {
  130               throw new InvalidAlgorithmParameterException
  131                   ("Exponent size must not be larger than modulus size");
  132           }
  133           this.random = random;
  134       }
  135   
  136       /**
  137        * Generates a key pair.
  138        *
  139        * @return the new key pair
  140        */
  141       public KeyPair generateKeyPair() {
  142           if (random == null) {
  143               random = SunJCE.RANDOM;
  144           }
  145   
  146           if (params == null) {
  147               try {
  148                   params = ParameterCache.getDHParameterSpec(pSize, random);
  149               } catch (GeneralSecurityException e) {
  150                   // should never happen
  151                   throw new ProviderException(e);
  152               }
  153           }
  154   
  155           BigInteger p = params.getP();
  156           BigInteger g = params.getG();
  157   
  158           if (lSize <= 0) {
  159               // use an exponent size of (pSize / 2) but at least 384 bits
  160               lSize = Math.max(384, pSize >> 1);
  161               // if lSize is larger than pSize, limit by pSize
  162               lSize = Math.min(lSize, pSize);
  163           }
  164   
  165           BigInteger x;
  166           BigInteger pMinus2 = p.subtract(BigInteger.valueOf(2));
  167   
  168           //
  169           // Handbook of Applied Cryptography:  Menezes, et.al.
  170           // Repeat if the following does not hold:
  171           //     1 <= x <= p-2
  172           //
  173           do {
  174               // generate random x up to 2^lSize bits long
  175               x = new BigInteger(lSize, random);
  176           } while ((x.compareTo(BigInteger.ONE) < 0) ||
  177               ((x.compareTo(pMinus2) > 0)));
  178   
  179           // calculate public value y
  180           BigInteger y = g.modPow(x, p);
  181   
  182           DHPublicKey pubKey = new DHPublicKey(y, p, g, lSize);
  183           DHPrivateKey privKey = new DHPrivateKey(x, p, g, lSize);
  184           return new KeyPair(pubKey, privKey);
  185       }
  186   }

Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]