Reputation: 1
Is it possible to encrypt data with multiple encryption algorithms using the BouncyCastle open source library? I have written the code below to pass the output from one cipher as input to the other cipher but I am always getting the same output bytes.
Thanks in advance, Ahmad Yassin
Boolean ProcessFile(
PaddedBufferedBlockCipher aesCipher,
PaddedBufferedBlockCipher serpentCipher,
PaddedBufferedBlockCipher twofishCipher,
FileStream fin,
FileStream fout,
int addOnLength)
{
int inputSize = aesCipher.GetBlockSize();
int outputSize = aesCipher.GetOutputSize(inputSize);
byte[] inputBuffer = new byte[inputSize];
byte[] outBuffer = new byte[outputSize];
long fileLenght = fin.Length - addOnLength;
long progressStep = fileLenght >= 100 ? fileLenght / 100 : fileLenght;
long totalLength = 0;
int inLength = 0;
int outLength;
try
{
while ((inLength = fin.Read(inputBuffer, 0, inputSize)) != 0)
{
outLength = aesCipher.ProcessBytes(inputBuffer, 0, inLength, outBuffer, 0);
outLength = serpentCipher.ProcessBytes(outBuffer, 0, outLength, outBuffer, 0);
outLength = twofishCipher.ProcessBytes(outBuffer, 0, outLength, outBuffer, 0);
fout.Write(outBuffer, 0, outLength);
totalLength += inLength;
if (totalLength >= progressStep)
{
DoProgressChanged();
totalLength = totalLength % progressStep;
}
}
outLength = aesCipher.DoFinal(outBuffer, 0);
fout.Write(outBuffer, 0, outLength);
fout.Close();
fin.Close();
return true;
}
catch (IOException e)
{
throw new IOException(e.Message);
}
}
public event EventHandler ProgressChanged;
private void DoProgressChanged()
{
if (this.ProgressChanged != null)
this.ProgressChanged(this, new EventArgs());
}
enum Mode { Encription = 1, Decription = 0 }
enum Algorithm { AES = 1, Serpent = 2, Twofish = 3 }
PaddedBufferedBlockCipher GetCipher(Algorithm algorithm, Mode mode, byte[] key, byte[] iv)
{
IBlockCipher blockCipher;
ICipherParameters parameters = new ParametersWithIV(new KeyParameter(key), iv);
switch (algorithm)
{
case Algorithm.AES:
blockCipher = new AesFastEngine();
break;
case Algorithm.Serpent:
blockCipher = new SerpentEngine();
break;
case Algorithm.Twofish:
blockCipher = new TwofishEngine();
break;
default:
blockCipher = new AesFastEngine();
break;
}
IBlockCipher cbcblockCipher = new CbcBlockCipher(blockCipher);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbcblockCipher, new Pkcs7Padding());
cipher.Init(mode == Mode.Encription, parameters);
return cipher;
}
Upvotes: 0
Views: 614
Reputation: 94078
Of course it is possible, but I would strongly suggest you use some kind of connected streams, or perform three passes over the buffer (first AES, then Serpent, then TwoFish or any other order). Don't perform a block size encryption for every cipher as you do now, as block sizes and other parameters may differ.
Of course, the usefulness of using three separate encryption algorithms is debatable.
Upvotes: 1