com.fitbur.bouncycastle.pkcs.jcajce.JcePKCSPBEOutputEncryptorBuilder Maven / Gradle / Ivy
package com.fitbur.bouncycastle.pkcs.jcajce;
import java.io.OutputStream;
import java.security.Provider;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import com.fitbur.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.fitbur.bouncycastle.asn1.ASN1Primitive;
import com.fitbur.bouncycastle.asn1.bc.BCObjectIdentifiers;
import com.fitbur.bouncycastle.asn1.pkcs.EncryptionScheme;
import com.fitbur.bouncycastle.asn1.pkcs.KeyDerivationFunc;
import com.fitbur.bouncycastle.asn1.pkcs.PBES2Parameters;
import com.fitbur.bouncycastle.asn1.pkcs.PBKDF2Params;
import com.fitbur.bouncycastle.asn1.pkcs.PKCS12PBEParams;
import com.fitbur.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.fitbur.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.fitbur.bouncycastle.crypto.PBEParametersGenerator;
import com.fitbur.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import com.fitbur.bouncycastle.jcajce.util.JcaJceHelper;
import com.fitbur.bouncycastle.jcajce.util.NamedJcaJceHelper;
import com.fitbur.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import com.fitbur.bouncycastle.operator.DefaultSecretKeySizeProvider;
import com.fitbur.bouncycastle.operator.GenericKey;
import com.fitbur.bouncycastle.operator.OperatorCreationException;
import com.fitbur.bouncycastle.operator.OutputEncryptor;
import com.fitbur.bouncycastle.operator.SecretKeySizeProvider;
public class JcePKCSPBEOutputEncryptorBuilder
{
private JcaJceHelper helper = new DefaultJcaJceHelper();
private ASN1ObjectIdentifier algorithm;
private ASN1ObjectIdentifier keyEncAlgorithm;
private SecureRandom random;
private SecretKeySizeProvider keySizeProvider = DefaultSecretKeySizeProvider.INSTANCE;
public JcePKCSPBEOutputEncryptorBuilder(ASN1ObjectIdentifier algorithm)
{
if (isPKCS12(algorithm))
{
this.algorithm = algorithm;
this.keyEncAlgorithm = algorithm;
}
else
{
this.algorithm = PKCSObjectIdentifiers.id_PBES2;
this.keyEncAlgorithm = algorithm;
}
}
public JcePKCSPBEOutputEncryptorBuilder setProvider(Provider provider)
{
this.helper = new ProviderJcaJceHelper(provider);
return this;
}
public JcePKCSPBEOutputEncryptorBuilder setProvider(String providerName)
{
this.helper = new NamedJcaJceHelper(providerName);
return this;
}
/**
* Set the lookup provider of AlgorithmIdentifier returning key_size_in_bits used to
* handle PKCS5 com.fitburcryption.
*
* @param keySizeProvider a provider of integer secret key sizes.
*
* @return the current builder.
*/
public JcePKCSPBEOutputEncryptorBuilder setKeySizeProvider(SecretKeySizeProvider keySizeProvider)
{
this.keySizeProvider = keySizeProvider;
return this;
}
public OutputEncryptor build(final char[] password)
throws OperatorCreationException
{
final Cipher cipher;
SecretKey key;
if (random == null)
{
random = new SecureRandom();
}
final AlgorithmIdentifier encryptionAlg;
final byte[] salt = new byte[20];
final int iterationCount = 1024;
random.nextBytes(salt);
try
{
if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds))
{
PBEKeySpec pbeSpec = new PBEKeySpec(password);
SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId());
PBEParameterSpec com.fitburfParams = new PBEParameterSpec(salt, iterationCount);
key = keyFact.generateSecret(pbeSpec);
cipher = helper.createCipher(algorithm.getId());
cipher.init(Cipher.ENCRYPT_MODE, key, com.fitburfParams);
encryptionAlg = new AlgorithmIdentifier(algorithm, new PKCS12PBEParams(salt, iterationCount));
}
else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
{
SecretKeyFactory keyFact = helper.createSecretKeyFactory(PKCSObjectIdentifiers.id_PBKDF2.getId());
key = keyFact.generateSecret(new PBEKeySpec(password, salt, iterationCount, keySizeProvider.getKeySize(new AlgorithmIdentifier(keyEncAlgorithm))));
cipher = helper.createCipher(keyEncAlgorithm.getId());
cipher.init(Cipher.ENCRYPT_MODE, key, random);
PBES2Parameters algParams = new PBES2Parameters(
new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount)),
new EncryptionScheme(keyEncAlgorithm, ASN1Primitive.fromByteArray(cipher.getParameters().getEncoded())));
encryptionAlg = new AlgorithmIdentifier(algorithm, algParams);
}
else
{
throw new OperatorCreationException("unrecognised algorithm");
}
return new OutputEncryptor()
{
public AlgorithmIdentifier getAlgorithmIdentifier()
{
return encryptionAlg;
}
public OutputStream getOutputStream(OutputStream out)
{
return new CipherOutputStream(out, cipher);
}
public GenericKey getKey()
{
if (isPKCS12(encryptionAlg.getAlgorithm()))
{
return new GenericKey(encryptionAlg, PBEParametersGenerator.PKCS5PasswordToBytes(password));
}
else
{
return new GenericKey(encryptionAlg, PBEParametersGenerator.PKCS12PasswordToBytes(password));
}
}
};
}
catch (Exception e)
{
throw new OperatorCreationException("unable to create OutputEncryptor: " + e.getMessage(), e);
}
}
private boolean isPKCS12(ASN1ObjectIdentifier algorithm)
{
return algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)
|| algorithm.on(BCObjectIdentifiers.bc_pbe_sha1_pkcs12)
|| algorithm.on(BCObjectIdentifiers.bc_pbe_sha256_pkcs12);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy