org.cryptacular.pbe.AbstractEncryptionScheme Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cryptacular Show documentation
Show all versions of cryptacular Show documentation
The spectacular complement to the Bouncy Castle crypto API for Java.
/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.pbe;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.io.CipherInputStream;
import org.bouncycastle.crypto.io.CipherOutputStream;
import org.bouncycastle.util.io.Streams;
import org.cryptacular.CryptoException;
/**
* Abstract base class for password-based encryption schemes based on salt data and iterated hashing as the basis of the
* key derivation function.
*
* NOTE: Classes derived from this class are not thread safe. In particular, care should be take to prevent multiple
* threads from performing encryption and/or decryption concurrently.
*
* @author Middleware Services
* @version $Revision: 2744 $
*/
public abstract class AbstractEncryptionScheme implements EncryptionScheme
{
/** Cipher used for encryption and decryption. */
private BufferedBlockCipher cipher;
/** Cipher initialization parameters. */
private CipherParameters parameters;
@Override
public byte[] encrypt(final byte[] plaintext)
{
cipher.init(true, parameters);
return process(plaintext);
}
@Override
public void encrypt(final InputStream in, final OutputStream out)
throws IOException
{
cipher.init(true, parameters);
Streams.pipeAll(in, new CipherOutputStream(out, cipher));
}
@Override
public byte[] decrypt(final byte[] ciphertext)
{
cipher.init(false, parameters);
return process(ciphertext);
}
@Override
public void decrypt(final InputStream in, final OutputStream out)
throws IOException
{
cipher.init(false, parameters);
Streams.pipeAll(new CipherInputStream(in, cipher), out);
}
/**
* Sets the block cipher used for encryption/decryption.
*
* @param bufferedBlockCipher Buffered block cipher.
*/
protected void setCipher(final BufferedBlockCipher bufferedBlockCipher)
{
if (bufferedBlockCipher == null) {
throw new IllegalArgumentException("Block cipher cannot be null");
}
this.cipher = bufferedBlockCipher;
}
/**
* Sets block cipher initialization parameters.
*
* @param parameters Cipher-specific init params.
*/
protected void setCipherParameters(final CipherParameters parameters)
{
if (parameters == null) {
throw new IllegalArgumentException("Cipher parameters cannot be null");
}
this.parameters = parameters;
}
/**
* Run the given data through the initialized underlying cipher and return the result.
*
* @param input Input data.
*
* @return Result of cipher acting on input.
*/
private byte[] process(final byte[] input)
{
final byte[] output = new byte[cipher.getOutputSize(input.length)];
int processed = cipher.processBytes(input, 0, input.length, output, 0);
try {
processed += cipher.doFinal(output, processed);
} catch (InvalidCipherTextException e) {
throw new CryptoException("Cipher error", e);
}
return Arrays.copyOfRange(output, 0, processed);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy