1   /* $RCSfile: DESede2KeySecretKeyGeneratorImpl.java,v $
2    * $Revision: 1.4 $
3    * $Date: 2002/11/23 11:09:57 $
4    * $Author: uwe_guenther $
5    * $State: Exp $
6    *
7    * Created on August 13, 2001 2:51 PM
8    *
9    * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10   *
11   * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12   * ServiceProvider is a library, written in JavaTM, that should be 
13   * used in HBCI banking applications (clients and may be servers),
14   * to do cryptographic operations.
15   *
16   * The jhbci library is free software; you can redistribute it and/or
17   * modify it under the terms of the GNU Lesser General Public
18   * License as published by the Free Software Foundation; either
19   * version 2.1 of the License, or (at your option) any later version.
20   *
21   * The jhbci library is distributed in the hope that it will be useful,
22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   * Lesser General Public License for more details.
25   *
26   * You should have received a copy of the GNU Lesser General Public
27   * License along with this library; if not, write to the Free Software
28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29   *
30   */
31  
32  package de.cscc.crypto.provider;
33  
34  import java.security.InvalidAlgorithmParameterException;
35  import java.security.InvalidKeyException;
36  import java.security.InvalidParameterException;
37  import java.security.SecureRandom;
38  import java.security.spec.AlgorithmParameterSpec;
39  
40  import javax.crypto.SecretKey;
41  
42  import de.cscc.crypto.provider.spec.DESede2KeySpec;
43  
44  /** 
45   * DESede2KeySecretKeyGeneratorImpl Class.
46   *
47   * @author  <a href=mailto:uwe@cscc.de>Uwe G&uuml;nther</a>
48   * @version $Revision: 1.4 $
49   */
50  final class DESede2KeySecretKeyGeneratorImpl {
51  
52      /** A reference to the secure random object. */    
53      private SecureRandom random = new SecureRandom();
54      
55      /** Creates new DESede2KeySecretKeyGeneratorImpl.*/
56      DESede2KeySecretKeyGeneratorImpl() {}
57  
58      /** 
59       * Returns a string representation of the object. 
60       *
61       * @return a string representation of the object.
62       */
63      public String toString() {
64          return "[DESede2KeySecretKeyGenerator]";
65      }
66      
67      /** 
68       * Initializes the key generator.
69       *
70       * @param random the source of randomness for this generator.
71       */
72      void init(SecureRandom random) {
73          if (random != null) {
74              this.random = random;
75          }
76      }
77      
78      /** 
79       * Initializes this key generator for a certain keysize, using the given
80       * source of randomness. We support only 112 bit and 128 bit keysize,
81       * which means the refers to the same result. 
82       *
83       * @param keysize the keysize. This is an algorithm-specific metric,
84       *                specified in number of bits.
85       * @param random the source of randomness for this key generator.
86       * @throws InvalidParameterException if keysize is wrong or not supported.
87       */
88      void init(int keysize, SecureRandom random) 
89              throws InvalidParameterException {
90          if ((keysize != 112) && (keysize != 128)){
91              throw new InvalidParameterException("Requested key size should be "
92                      + "112 bit or 128 bit, not " + keysize + " bit.");
93          }
94          
95          init(random);
96      }
97      
98      /** 
99       * Initializes the key generator with the specified parameter
100      * set and a user-provided source of randomness. The JHBCI
101      * key generator implementation don't use any AlgorithmParameterSpec's.
102      * This means if you want to init the KeyGenerator Object with this
103      * method <code>params</code> have to be null or
104      * InvalidAlgorithmParameterException will be thrown.
105      *
106      * @param params the key generation parameters.
107      * @param random the source of randomness for this key generator.
108      * @exception InvalidAlgorithmParameterException if <code>params</code> is
109      * inappropriate for this key generator. We only support <code>null</code>
110      * as parameter for <code>params</code>.
111      */
112     void init(AlgorithmParameterSpec params, SecureRandom random) 
113             throws InvalidAlgorithmParameterException {
114         if (params != null) {
115             throw new InvalidAlgorithmParameterException("This KeyGenerator "
116                     + "does not support or use any AlgorithmParameterSpec." 
117                     + "Set parameter AlgorithmParameterSpec params to null, " 
118                     + "or use init(SecureRandom random) instead.");
119         }
120         
121         init(random);
122     }
123     
124     /** 
125      * Generates a secret key. This method can re-used more than once
126      * for the KeyGenerator Object to generate a lot of SecretKey's.
127      *
128      * @return the new key.
129      */
130     SecretKey generateKey() {
131         //Get memory for the random value.
132         byte[] generatedKeyBytes = new byte[16];
133         
134         //Initialize the KeySpec.
135         DESede2KeySpec generatedKeySpec = null;
136         
137         for (boolean reloop =true; reloop == true;) {
138             //Generate 16 random bytes.
139             this.random.nextBytes(generatedKeyBytes);
140             try{
141                 //Put the 16 random bytes int the KeySpec and chack if they
142                 //are weak or semi weak.
143                 generatedKeySpec = new DESede2KeySpec(generatedKeyBytes);
144                 //If no exception was thrown, we break out of the loop;
145                 reloop = false;
146             } catch (InvalidKeyException e) {
147                 //If an InvalidKeyException was thrown (means the key 
148                 //was weak or semi weak), we loop again;
149                 reloop = true;
150             }
151         }
152         
153         //Put the KeySpec in a new DESede2KeySecretKeyImpl and return the
154         //new DESede2KeySecretKeyImpl upcasted to SecretKey.
155         return new DESede2KeySecretKeyImpl(generatedKeySpec);
156     }
157 }
158