Home | History | Annotate | Download | only in generators
      1 package org.bouncycastle.crypto.generators;
      2 
      3 import org.bouncycastle.crypto.CipherParameters;
      4 import org.bouncycastle.crypto.Digest;
      5 import org.bouncycastle.crypto.PBEParametersGenerator;
      6 import org.bouncycastle.crypto.params.KeyParameter;
      7 import org.bouncycastle.crypto.params.ParametersWithIV;
      8 
      9 /**
     10  * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 1.
     11  * Note this generator is limited to the size of the hash produced by the
     12  * digest used to drive it.
     13  * <p>
     14  * The document this implementation is based on can be found at
     15  * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
     16  * RSA's PKCS5 Page</a>
     17  */
     18 public class PKCS5S1ParametersGenerator
     19     extends PBEParametersGenerator
     20 {
     21     private Digest  digest;
     22 
     23     /**
     24      * Construct a PKCS 5 Scheme 1 Parameters generator.
     25      *
     26      * @param digest the digest to be used as the source of derived keys.
     27      */
     28     public PKCS5S1ParametersGenerator(
     29         Digest  digest)
     30     {
     31         this.digest = digest;
     32     }
     33 
     34     /**
     35      * the derived key function, the ith hash of the password and the salt.
     36      */
     37     private byte[] generateDerivedKey()
     38     {
     39         byte[] digestBytes = new byte[digest.getDigestSize()];
     40 
     41         digest.update(password, 0, password.length);
     42         digest.update(salt, 0, salt.length);
     43 
     44         digest.doFinal(digestBytes, 0);
     45         for (int i = 1; i < iterationCount; i++)
     46         {
     47             digest.update(digestBytes, 0, digestBytes.length);
     48             digest.doFinal(digestBytes, 0);
     49         }
     50 
     51         return digestBytes;
     52     }
     53 
     54     /**
     55      * Generate a key parameter derived from the password, salt, and iteration
     56      * count we are currently initialised with.
     57      *
     58      * @param keySize the size of the key we want (in bits)
     59      * @return a KeyParameter object.
     60      * @exception IllegalArgumentException if the key length larger than the base hash size.
     61      */
     62     public CipherParameters generateDerivedParameters(
     63         int keySize)
     64     {
     65         keySize = keySize / 8;
     66 
     67         if (keySize > digest.getDigestSize())
     68         {
     69             throw new IllegalArgumentException(
     70                    "Can't generate a derived key " + keySize + " bytes long.");
     71         }
     72 
     73         byte[]  dKey = generateDerivedKey();
     74 
     75         return new KeyParameter(dKey, 0, keySize);
     76     }
     77 
     78     /**
     79      * Generate a key with initialisation vector parameter derived from
     80      * the password, salt, and iteration count we are currently initialised
     81      * with.
     82      *
     83      * @param keySize the size of the key we want (in bits)
     84      * @param ivSize the size of the iv we want (in bits)
     85      * @return a ParametersWithIV object.
     86      * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size.
     87      */
     88     public CipherParameters generateDerivedParameters(
     89         int     keySize,
     90         int     ivSize)
     91     {
     92         keySize = keySize / 8;
     93         ivSize = ivSize / 8;
     94 
     95         if ((keySize + ivSize) > digest.getDigestSize())
     96         {
     97             throw new IllegalArgumentException(
     98                    "Can't generate a derived key " + (keySize + ivSize) + " bytes long.");
     99         }
    100 
    101         byte[]  dKey = generateDerivedKey();
    102 
    103         return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
    104     }
    105 
    106     /**
    107      * Generate a key parameter for use with a MAC derived from the password,
    108      * salt, and iteration count we are currently initialised with.
    109      *
    110      * @param keySize the size of the key we want (in bits)
    111      * @return a KeyParameter object.
    112      * @exception IllegalArgumentException if the key length larger than the base hash size.
    113      */
    114     public CipherParameters generateDerivedMacParameters(
    115         int keySize)
    116     {
    117         return generateDerivedParameters(keySize);
    118     }
    119 }
    120