org.cryptacular.bean.AbstractBlockCipherBean 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.bean;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import org.cryptacular.CiphertextHeader;
import org.cryptacular.StreamException;
import org.cryptacular.adapter.BlockCipherAdapter;
import org.cryptacular.generator.Nonce;
import org.cryptacular.util.StreamUtil;
/**
* Base class for all cipher beans that use block cipher.
*
* @author Middleware Services
*/
public abstract class AbstractBlockCipherBean extends AbstractCipherBean
{
/** Creates a new instance. */
public AbstractBlockCipherBean() {}
/**
* Creates a new instance by specifying all properties.
*
* @param keyStore Key store containing encryption key.
* @param keyAlias Name of encryption key entry in key store.
* @param keyPassword Password used to decrypt key entry in keystore.
* @param nonce Nonce/IV generator.
*/
public AbstractBlockCipherBean(
final KeyStore keyStore,
final String keyAlias,
final String keyPassword,
final Nonce nonce)
{
super(keyStore, keyAlias, keyPassword, nonce);
}
@Override
protected byte[] process(final CiphertextHeader header, final boolean mode, final byte[] input)
{
final BlockCipherAdapter cipher = newCipher(header, mode);
int outOff;
final int inOff;
final int length;
final byte[] output;
if (mode) {
final byte[] headerBytes = header.encode();
final int outSize = headerBytes.length + cipher.getOutputSize(input.length);
output = new byte[outSize];
System.arraycopy(headerBytes, 0, output, 0, headerBytes.length);
inOff = 0;
outOff = headerBytes.length;
length = input.length;
} else {
outOff = 0;
inOff = header.getLength();
length = input.length - inOff;
final int outSize = cipher.getOutputSize(length);
output = new byte[outSize];
}
outOff += cipher.processBytes(input, inOff, length, output, outOff);
outOff += cipher.doFinal(output, outOff);
if (outOff < output.length) {
final byte[] copy = new byte[outOff];
System.arraycopy(output, 0, copy, 0, outOff);
return copy;
}
return output;
}
@Override
protected void process(
final CiphertextHeader header,
final boolean mode,
final InputStream input,
final OutputStream output)
{
final BlockCipherAdapter cipher = newCipher(header, mode);
final int outSize = cipher.getOutputSize(StreamUtil.CHUNK_SIZE);
final byte[] outBuf = new byte[Math.max(outSize, StreamUtil.CHUNK_SIZE)];
StreamUtil.pipeAll(
input,
output,
(in, inOff, len, out) -> {
final int n = cipher.processBytes(in, inOff, len, outBuf, 0);
out.write(outBuf, 0, n);
});
final int n = cipher.doFinal(outBuf, 0);
try {
output.write(outBuf, 0, n);
} catch (IOException e) {
throw new StreamException(e);
}
}
/**
* Creates a new cipher adapter instance suitable for the block cipher used by this class.
*
* @param header Ciphertext header.
* @param mode True for encryption; false for decryption.
*
* @return Block cipher adapter that wraps an initialized block cipher that is ready for use in the given mode.
*/
protected abstract BlockCipherAdapter newCipher(CiphertextHeader header, boolean mode);
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy