com.fitbur.bouncycastle.cms.PasswordRecipientInfoGenerator Maven / Gradle / Ivy
package com.fitbur.bouncycastle.cms;
import java.security.SecureRandom;
import com.fitbur.bouncycastle.asn1.ASN1EncodableVector;
import com.fitbur.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.fitbur.bouncycastle.asn1.ASN1OctetString;
import com.fitbur.bouncycastle.asn1.DEROctetString;
import com.fitbur.bouncycastle.asn1.DERSequence;
import com.fitbur.bouncycastle.asn1.cms.PasswordRecipientInfo;
import com.fitbur.bouncycastle.asn1.cms.RecipientInfo;
import com.fitbur.bouncycastle.asn1.pkcs.PBKDF2Params;
import com.fitbur.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.fitbur.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.fitbur.bouncycastle.operator.GenericKey;
public abstract class PasswordRecipientInfoGenerator
implements RecipientInfoGenerator
{
private char[] password;
private AlgorithmIdentifier keyDerivationAlgorithm;
private ASN1ObjectIdentifier kekAlgorithm;
private SecureRandom random;
private int schemeID;
private int keySize;
private int blockSize;
protected PasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password)
{
this(kekAlgorithm, password, getKeySize(kekAlgorithm), ((Integer)PasswordRecipientInformation.BLOCKSIZES.get(kekAlgorithm)).intValue());
}
protected PasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password, int keySize, int blockSize)
{
this.password = password;
this.schemeID = PasswordRecipient.PKCS5_SCHEME2_UTF8;
this.kekAlgorithm = kekAlgorithm;
this.keySize = keySize;
this.blockSize = blockSize;
}
private static int getKeySize(ASN1ObjectIdentifier kekAlgorithm)
{
Integer size = (Integer)PasswordRecipientInformation.KEYSIZES.get(kekAlgorithm);
if (size == null)
{
throw new IllegalArgumentException("cannot find key size for algorithm: " + kekAlgorithm);
}
return size.intValue();
}
public PasswordRecipientInfoGenerator setPasswordConversionScheme(int schemeID)
{
this.schemeID = schemeID;
return this;
}
public PasswordRecipientInfoGenerator setSaltAndIterationCount(byte[] salt, int iterationCount)
{
this.keyDerivationAlgorithm = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount));
return this;
}
public PasswordRecipientInfoGenerator setSecureRandom(SecureRandom random)
{
this.random = random;
return this;
}
public RecipientInfo generate(GenericKey contentEncryptionKey)
throws CMSException
{
byte[] iv = new byte[blockSize]; /// TODO: set IV size properly!
if (random == null)
{
random = new SecureRandom();
}
random.nextBytes(iv);
if (keyDerivationAlgorithm == null)
{
byte[] salt = new byte[20];
random.nextBytes(salt);
keyDerivationAlgorithm = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, 1024));
}
byte[] encodedPassword = CMSUtils.getPasswordBytes(schemeID, password);
byte[] com.fitburrivedKey = calculateDerivedKey(encodedPassword, keyDerivationAlgorithm, keySize);
AlgorithmIdentifier kekAlgorithmId = new AlgorithmIdentifier(kekAlgorithm, new DEROctetString(iv));
byte[] encryptedKeyBytes = generateEncryptedBytes(kekAlgorithmId, com.fitburrivedKey, contentEncryptionKey);
ASN1OctetString encryptedKey = new DEROctetString(encryptedKeyBytes);
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(kekAlgorithm);
v.add(new DEROctetString(iv));
AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(
PKCSObjectIdentifiers.id_alg_PWRI_KEK, new DERSequence(v));
return new RecipientInfo(new PasswordRecipientInfo(keyDerivationAlgorithm,
keyEncryptionAlgorithm, encryptedKey));
}
protected abstract byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier com.fitburrivationAlgorithm, int keySize)
throws CMSException;
protected abstract byte[] generateEncryptedBytes(AlgorithmIdentifier algorithm, byte[] com.fitburrivedKey, GenericKey contentEncryptionKey)
throws CMSException;
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy