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.digests.MD5Digest;
      7 import org.bouncycastle.crypto.params.KeyParameter;
      8 import org.bouncycastle.crypto.params.ParametersWithIV;
      9 
     10 /**
     11  * Generator for PBE derived keys and ivs as usd by OpenSSL.
     12  * <p>
     13  * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
     14  * iteration count of 1.
     15  * <p>
     16  */
     17 public class OpenSSLPBEParametersGenerator
     18     extends PBEParametersGenerator
     19 {
     20     private Digest  digest = new MD5Digest();
     21 
     22     /**
     23      * Construct a OpenSSL Parameters generator.
     24      */
     25     public OpenSSLPBEParametersGenerator()
     26     {
     27     }
     28 
     29     /**
     30      * Initialise - note the iteration count for this algorithm is fixed at 1.
     31      *
     32      * @param password password to use.
     33      * @param salt salt to use.
     34      */
     35     public void init(
     36        byte[] password,
     37        byte[] salt)
     38     {
     39         super.init(password, salt, 1);
     40     }
     41 
     42     /**
     43      * the derived key function, the ith hash of the password and the salt.
     44      */
     45     private byte[] generateDerivedKey(
     46         int bytesNeeded)
     47     {
     48         byte[]  buf = new byte[digest.getDigestSize()];
     49         byte[]  key = new byte[bytesNeeded];
     50         int     offset = 0;
     51 
     52         for (;;)
     53         {
     54             digest.update(password, 0, password.length);
     55             digest.update(salt, 0, salt.length);
     56 
     57             digest.doFinal(buf, 0);
     58 
     59             int len = (bytesNeeded > buf.length) ? buf.length : bytesNeeded;
     60             System.arraycopy(buf, 0, key, offset, len);
     61             offset += len;
     62 
     63             // check if we need any more
     64             bytesNeeded -= len;
     65             if (bytesNeeded == 0)
     66             {
     67                 break;
     68             }
     69 
     70             // do another round
     71             digest.reset();
     72             digest.update(buf, 0, buf.length);
     73         }
     74 
     75         return key;
     76     }
     77 
     78     /**
     79      * Generate a key parameter derived from the password, salt, and iteration
     80      * count we are currently initialised with.
     81      *
     82      * @param keySize the size of the key we want (in bits)
     83      * @return a KeyParameter object.
     84      * @exception IllegalArgumentException if the key length larger than the base hash size.
     85      */
     86     public CipherParameters generateDerivedParameters(
     87         int keySize)
     88     {
     89         keySize = keySize / 8;
     90 
     91         byte[]  dKey = generateDerivedKey(keySize);
     92 
     93         return new KeyParameter(dKey, 0, keySize);
     94     }
     95 
     96     /**
     97      * Generate a key with initialisation vector parameter derived from
     98      * the password, salt, and iteration count we are currently initialised
     99      * with.
    100      *
    101      * @param keySize the size of the key we want (in bits)
    102      * @param ivSize the size of the iv we want (in bits)
    103      * @return a ParametersWithIV object.
    104      * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size.
    105      */
    106     public CipherParameters generateDerivedParameters(
    107         int     keySize,
    108         int     ivSize)
    109     {
    110         keySize = keySize / 8;
    111         ivSize = ivSize / 8;
    112 
    113         byte[]  dKey = generateDerivedKey(keySize + ivSize);
    114 
    115         return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
    116     }
    117 
    118     /**
    119      * Generate a key parameter for use with a MAC derived from the password,
    120      * salt, and iteration count we are currently initialised with.
    121      *
    122      * @param keySize the size of the key we want (in bits)
    123      * @return a KeyParameter object.
    124      * @exception IllegalArgumentException if the key length larger than the base hash size.
    125      */
    126     public CipherParameters generateDerivedMacParameters(
    127         int keySize)
    128     {
    129         return generateDerivedParameters(keySize);
    130     }
    131 }
    132