001: package org.bouncycastle.crypto.generators;
002:
003: import org.bouncycastle.crypto.CipherParameters;
004: import org.bouncycastle.crypto.Digest;
005: import org.bouncycastle.crypto.PBEParametersGenerator;
006: import org.bouncycastle.crypto.params.KeyParameter;
007: import org.bouncycastle.crypto.params.ParametersWithIV;
008:
009: /**
010: * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 1.
011: * Note this generator is limited to the size of the hash produced by the
012: * digest used to drive it.
013: * <p>
014: * The document this implementation is based on can be found at
015: * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
016: * RSA's PKCS5 Page</a>
017: */
018: public class PKCS5S1ParametersGenerator extends PBEParametersGenerator {
019: private Digest digest;
020:
021: /**
022: * Construct a PKCS 5 Scheme 1 Parameters generator.
023: *
024: * @param digest the digest to be used as the source of derived keys.
025: */
026: public PKCS5S1ParametersGenerator(Digest digest) {
027: this .digest = digest;
028: }
029:
030: /**
031: * the derived key function, the ith hash of the password and the salt.
032: */
033: private byte[] generateDerivedKey() {
034: byte[] digestBytes = new byte[digest.getDigestSize()];
035:
036: digest.update(password, 0, password.length);
037: digest.update(salt, 0, salt.length);
038:
039: digest.doFinal(digestBytes, 0);
040: for (int i = 1; i < iterationCount; i++) {
041: digest.update(digestBytes, 0, digestBytes.length);
042: digest.doFinal(digestBytes, 0);
043: }
044:
045: return digestBytes;
046: }
047:
048: /**
049: * Generate a key parameter derived from the password, salt, and iteration
050: * count we are currently initialised with.
051: *
052: * @param keySize the size of the key we want (in bits)
053: * @return a KeyParameter object.
054: * @exception IllegalArgumentException if the key length larger than the base hash size.
055: */
056: public CipherParameters generateDerivedParameters(int keySize) {
057: keySize = keySize / 8;
058:
059: if (keySize > digest.getDigestSize()) {
060: throw new IllegalArgumentException(
061: "Can't generate a derived key " + keySize
062: + " bytes long.");
063: }
064:
065: byte[] dKey = generateDerivedKey();
066:
067: return new KeyParameter(dKey, 0, keySize);
068: }
069:
070: /**
071: * Generate a key with initialisation vector parameter derived from
072: * the password, salt, and iteration count we are currently initialised
073: * with.
074: *
075: * @param keySize the size of the key we want (in bits)
076: * @param ivSize the size of the iv we want (in bits)
077: * @return a ParametersWithIV object.
078: * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size.
079: */
080: public CipherParameters generateDerivedParameters(int keySize,
081: int ivSize) {
082: keySize = keySize / 8;
083: ivSize = ivSize / 8;
084:
085: if ((keySize + ivSize) > digest.getDigestSize()) {
086: throw new IllegalArgumentException(
087: "Can't generate a derived key "
088: + (keySize + ivSize) + " bytes long.");
089: }
090:
091: byte[] dKey = generateDerivedKey();
092:
093: return new ParametersWithIV(new KeyParameter(dKey, 0, keySize),
094: dKey, keySize, ivSize);
095: }
096:
097: /**
098: * Generate a key parameter for use with a MAC derived from the password,
099: * salt, and iteration count we are currently initialised with.
100: *
101: * @param keySize the size of the key we want (in bits)
102: * @return a KeyParameter object.
103: * @exception IllegalArgumentException if the key length larger than the base hash size.
104: */
105: public CipherParameters generateDerivedMacParameters(int keySize) {
106: return generateDerivedParameters(keySize);
107: }
108: }
|