PKCS5S1ParametersGenerator.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatpackage org.bouncycastle.crypto.generators; 2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport org.bouncycastle.crypto.CipherParameters; 4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport org.bouncycastle.crypto.Digest; 5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport org.bouncycastle.crypto.PBEParametersGenerator; 6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport org.bouncycastle.crypto.params.KeyParameter; 7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport org.bouncycastle.crypto.params.ParametersWithIV; 8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 1. 11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Note this generator is limited to the size of the hash produced by the 12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * digest used to drive it. 13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * <p> 14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * The document this implementation is based on can be found at 15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html> 16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * RSA's PKCS5 Page</a> 17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatpublic class PKCS5S1ParametersGenerator 19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat extends PBEParametersGenerator 20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat private Digest digest; 22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /** 24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Construct a PKCS 5 Scheme 1 Parameters generator. 25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @param digest the digest to be used as the source of derived keys. 27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat public PKCS5S1ParametersGenerator( 29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat Digest digest) 30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this.digest = digest; 32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /** 35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * the derived key function, the ith hash of the password and the salt. 36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat private byte[] generateDerivedKey() 38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat byte[] digestBytes = new byte[digest.getDigestSize()]; 40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat digest.update(password, 0, password.length); 42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat digest.update(salt, 0, salt.length); 43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat digest.doFinal(digestBytes, 0); 45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (int i = 1; i < iterationCount; i++) 46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat digest.update(digestBytes, 0, digestBytes.length); 48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat digest.doFinal(digestBytes, 0); 49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return digestBytes; 52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /** 55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Generate a key parameter derived from the password, salt, and iteration 56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * count we are currently initialised with. 57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @param keySize the size of the key we want (in bits) 59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @return a KeyParameter object. 60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @exception IllegalArgumentException if the key length larger than the base hash size. 61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat public CipherParameters generateDerivedParameters( 63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int keySize) 64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat keySize = keySize / 8; 66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 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