edu.vt.middleware.crypt.PbeKeyGenerator Maven / Gradle / Ivy
/*
$Id$
Copyright (C) 2007-2010 Virginia Tech.
All rights reserved.
SEE LICENSE FOR MORE INFORMATION
Author: Middleware Services
Email: [email protected]
Version: $Revision$
Updated: $Date$
*/
package edu.vt.middleware.crypt;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import edu.vt.middleware.crypt.digest.DigestAlgorithm;
import edu.vt.middleware.crypt.symmetric.SymmetricAlgorithm;
import org.bouncycastle.crypto.PBEParametersGenerator;
import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
/**
* Generates secret keys from passwords/phrases in support of password-based
* encryption (PBE).
*
* @author Middleware Services
* @version $Revision: 3 $
*/
public class PbeKeyGenerator
{
/**
* Default number of applications of mixing function during key generation.
*/
private static final int DEFAULT_ITERATIONS = 1024;
/** Number of bits in byte. */
private static final int BITS_IN_BYTE = 8;
/** Symmetric cipher algorithm for which this generator can generate keys. */
private SymmetricAlgorithm symmetricAlg;
/** Number of iterations "mixing" function is to be applied. */
private int iterations = DEFAULT_ITERATIONS;
/**
* Creates a key generator that can generate PBE keys for use with the given
* symmetric cipher algorithm.
*
* @param algorithm Symmetric cipher algorithm.
*/
public PbeKeyGenerator(final SymmetricAlgorithm algorithm)
{
symmetricAlg = algorithm;
}
/**
* Sets the number of iterations the mixing function is applied during key
* generations.
*
* @param n Number of applications of mixing function.
*/
public void setIterations(final int n)
{
iterations = n;
}
/**
* Generate a key from a text password using the PKCS#12 method described at
* http://www.rsa.com/rsalabs/node.asp?id=2138.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param digest Digest algorithm to use during key generation.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public SecretKey generatePkcs12(
final char[] password,
final int keyBitLength,
final DigestAlgorithm digest,
final byte[] salt)
{
return
generate(
new PKCS12ParametersGenerator(digest.getDigest()),
PBEParametersGenerator.PKCS12PasswordToBytes(password),
keyBitLength,
salt);
}
/**
* Generate a key/IV pair from a text password using the PKCS#12 method
* described at http://www.rsa.com/rsalabs/node.asp?id=2138.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param ivBitLength Size of generated IV in bits.
* @param digest Digest algorithm to use during key generation.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public KeyWithIV generatePkcs12(
final char[] password,
final int keyBitLength,
final int ivBitLength,
final DigestAlgorithm digest,
final byte[] salt)
{
return
generate(
new PKCS12ParametersGenerator(digest.getDigest()),
PBEParametersGenerator.PKCS12PasswordToBytes(password),
keyBitLength,
ivBitLength,
salt);
}
/**
* Generate a key from a text password using the PKCS#5 version 1 method
* described at http://www.rsa.com/rsalabs/node.asp?id=2127.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param digest Digest algorithm to use during key generation.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public SecretKey generatePkcs5v1(
final char[] password,
final int keyBitLength,
final DigestAlgorithm digest,
final byte[] salt)
{
final int minSize = keyBitLength / BITS_IN_BYTE;
if (digest.getDigest().getDigestSize() < minSize) {
throw new IllegalArgumentException(
"Digest is too small for chosen key size. " +
"Use a digest whose size is at least " + minSize + " bytes.");
}
return
generate(
new PKCS5S1ParametersGenerator(digest.getDigest()),
PBEParametersGenerator.PKCS5PasswordToBytes(password),
keyBitLength,
salt);
}
/**
* Generate a key/IV pair from a text password using the PKCS#5 version 1
* method described at http://www.rsa.com/rsalabs/node.asp?id=2127.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param ivBitLength Size of generated IV in bits.
* @param digest Digest algorithm to use during key generation.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public KeyWithIV generatePkcs5v1(
final char[] password,
final int keyBitLength,
final int ivBitLength,
final DigestAlgorithm digest,
final byte[] salt)
{
final int minSize = (keyBitLength + ivBitLength) / BITS_IN_BYTE;
if (digest.getDigest().getDigestSize() < minSize) {
throw new IllegalArgumentException(
"Digest is too small for chosen key + IV size. " +
"Use a digest whose size is at least " + minSize + " bytes.");
}
return
generate(
new PKCS5S1ParametersGenerator(digest.getDigest()),
PBEParametersGenerator.PKCS5PasswordToBytes(password),
keyBitLength,
ivBitLength,
salt);
}
/**
* Generate a key from a text password using the PKCS#5 version 2.0 method
* described at http://www.rsa.com/rsalabs/node.asp?id=2127. A SHA-1 digest is
* used as the calculation function.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public SecretKey generatePkcs5v2(
final char[] password,
final int keyBitLength,
final byte[] salt)
{
return
generate(
new PKCS5S2ParametersGenerator(),
PBEParametersGenerator.PKCS5PasswordToBytes(password),
keyBitLength,
salt);
}
/**
* Generate a key/IV pair from a text password using the PKCS#5 version 2.0
* method described at http://www.rsa.com/rsalabs/node.asp?id=2127. A SHA-1
* digest is used as the calculation function.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param ivBitLength Size of generated IV in bits.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public KeyWithIV generatePkcs5v2(
final char[] password,
final int keyBitLength,
final int ivBitLength,
final byte[] salt)
{
return
generate(
new PKCS5S2ParametersGenerator(),
PBEParametersGenerator.PKCS5PasswordToBytes(password),
keyBitLength,
ivBitLength,
salt);
}
/**
* Generate a key from a text password using a method based ok PKCS#5 version
* 2 that is consistent with that performed by the openssl enc operation.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public SecretKey generateOpenssl(
final char[] password,
final int keyBitLength,
final byte[] salt)
{
return
generate(
new OpenSSLPBEParametersGenerator(),
PBEParametersGenerator.PKCS5PasswordToBytes(password),
keyBitLength,
salt);
}
/**
* Generate a key/IV pair from a text password using a strategy compatible
* with the OpenSSL enc operation. The strategy is based on PKCS#5 version 2,
* but uses a MD5 hash instead of SHA1 and an iteration count of 1. For
* compatibility with OpenSSL, the IV size should be equal to key size.
*
* @param password Raw material used for key generation.
* @param keyBitLength Size of generated key in bits.
* @param ivBitLength Size of generated IV in bits.
* @param salt Key initialization data.
*
* @return Secret key based on password.
*/
public KeyWithIV generateOpenssl(
final char[] password,
final int keyBitLength,
final int ivBitLength,
final byte[] salt)
{
return
generate(
new OpenSSLPBEParametersGenerator(),
PBEParametersGenerator.PKCS5PasswordToBytes(password),
keyBitLength,
ivBitLength,
salt);
}
/**
* Generate an encryption key from a password using the given parameter
* generator.
*
* @param generator Key generator for specific PBE method.
* @param password Password as byte array (depends on PBE method).
* @param keyBitLength Size of generated key in bits.
* @param salt Key initialization data.
*
* @return Secret key derived from password using PBE key generation method.
*/
private SecretKey generate(
final PBEParametersGenerator generator,
final byte[] password,
final int keyBitLength,
final byte[] salt)
{
generator.init(password, salt, iterations);
final KeyParameter keyParam = (KeyParameter)
generator.generateDerivedParameters(keyBitLength);
final SecretKeySpec spec = new SecretKeySpec(
keyParam.getKey(),
symmetricAlg.getAlgorithm());
return spec;
}
/**
* Generate an encryption key/IV pair from a password using the given
* parameter generator.
*
* @param generator Key generator for specific PBE method.
* @param password Password as byte array (depends on PBE method).
* @param keyBitLength Size of generated key in bits.
* @param ivBitLength Size of generated IV in bits.
* @param salt Key initialization data.
*
* @return Secret key derived from password using PBE key generation method.
*/
private KeyWithIV generate(
final PBEParametersGenerator generator,
final byte[] password,
final int keyBitLength,
final int ivBitLength,
final byte[] salt)
{
generator.init(password, salt, iterations);
final ParametersWithIV params = (ParametersWithIV)
generator.generateDerivedParameters(keyBitLength, ivBitLength);
final KeyParameter keyParam = (KeyParameter) params.getParameters();
return
new KeyWithIV(
new SecretKeySpec(keyParam.getKey(), symmetricAlg.getAlgorithm()),
params.getIV());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy