@@ -79,7 +79,10 @@ public static SecretKey generateSecretKey(String alg, int keySize)
7979 // it after ESAPI 2.0 is released or users with encrypted data
8080 // using the new encryption / decryption may be forever screwed.
8181 // (See CAUTION, below, for details.) Strongly suggest that we
82- // at least review this one class!!! (See Issue # 81.)
82+ // at least review this one class!!! (See Issue # 81.) This includes
83+ // using HmacSHA1. If some other HMAC (e.g., HMAC-SHA256) needs to be used
84+ // it MUST be done before 2.0 goes GA. (Note: Not sure that HMAC-SHA256
85+ // is available in JDK 1.5 though.)
8386 /**
8487 * Compute a derived key from the keyDerivationKey for either encryption / decryption
8588 * or for authentication.
@@ -100,9 +103,11 @@ public static SecretKey generateSecretKey(String alg, int keySize)
100103 * key.
101104 * @param keySize The cipher's key size (in bits) for the {@code keyDerivationKey}.
102105 * Must have a minimum size of 56 bits and be an integral multiple of 8-bits.
103- * The derived key will have the same size as this.
106+ * <b>Note:</b> The derived key will have the same size as this.
104107 * @param purpose The purpose for the derived key. Must be either the
105- * string "encryption" or "authenticity".
108+ * string "encryption" or "authenticity". Use "encryption" for
109+ * creating a derived key to use for confidentiality, and "authenticity"
110+ * for a derived key to use with a MAC to ensure message authenticity.
106111 * @return The derived {@code SecretKey} to be used according
107112 * to the specified purpose.
108113 * @throws NoSuchAlgorithmException The {@code keyDerivationKey} has an unsupported
@@ -119,10 +124,12 @@ public static SecretKey generateSecretKey(String alg, int keySize)
119124 public static SecretKey computeDerivedKey (SecretKey keyDerivationKey , int keySize , String purpose )
120125 throws NoSuchAlgorithmException , InvalidKeyException , EncryptionException
121126 {
122- assert keyDerivationKey != null : "Master key cannot be null." ;
127+ // These really should be turned into actual runtime checks and an
128+ // IllegalArgumentException should be thrown if they are violated.
129+ assert keyDerivationKey != null : "Key derivation key cannot be null." ;
123130 // We would choose a larger minimum key size, but we want to be
124131 // able to accept DES for legacy encryption needs.
125- assert keySize >= 56 : "Master key has size of " + keySize + ", which is less than minimum of 56-bits." ;
132+ assert keySize >= 56 : "Key has size of " + keySize + ", which is less than minimum of 56-bits." ;
126133 assert (keySize % 8 ) == 0 : "Key size (" + keySize + ") must be a even multiple of 8-bits." ;
127134 assert purpose != null ;
128135 assert purpose .equals ("encryption" ) || purpose .equals ("authenticity" ) :
@@ -144,7 +151,11 @@ public static SecretKey computeDerivedKey(SecretKey keyDerivationKey, int keySiz
144151 // going to be 20 bytes but something different. Experiments show
145152 // that doesn't really matter though as the SecretKeySpec CTOR on
146153 // the following line still returns the appropriate sized key for
147- // HmacSHA1.
154+ // HmacSHA1. So, if keyDerivationKey was originally (say) a 56-bit
155+ // DES key, then there is apparently some key-stretching going on here
156+ // under the hood to create 'sk' so that it is 20 bytes. I cannot vouch
157+ // for how secure this key-stretching is. Worse, it might not be specified
158+ // as to *how* it is done and left to each JCE provider.
148159 SecretKey sk = new SecretKeySpec (keyDerivationKey .getEncoded (), "HmacSHA1" );
149160 Mac mac = null ;
150161
@@ -171,7 +182,8 @@ public static SecretKey computeDerivedKey(SecretKey keyDerivationKey, int keySiz
171182 // in when previously initialized via a call to init(Key) or
172183 // init(Key, AlgorithmParameterSpec). That is, the object is reset
173184 // and available to generate another MAC from the same key, if
174- // desired, via new calls to update and doFinal."
185+ // desired, via new calls to update and doFinal." Therefore, we do
186+ // not do an explicit reset().
175187 tmpKey = mac .doFinal (inputBytes );
176188 if ( tmpKey .length >= keySize ) {
177189 len = keySize ;
@@ -184,6 +196,7 @@ public static SecretKey computeDerivedKey(SecretKey keyDerivationKey, int keySiz
184196 destPos += len ;
185197 } while ( totalCopied < keySize );
186198
199+ // Convert it back into a SecretKey of the appropriate type.
187200 return new SecretKeySpec (derivedKey , keyDerivationKey .getAlgorithm ());
188201 }
189202
0 commit comments