I am attempting to encrypt and decrypt data using the bouncycastle library, upon decryption of the data the data the first block of information is corrupt as if it failed to be successfully decrypted and the last block was completely lost. I am new to the bouncycastle library, and I have been searching all over internet trying to find a sensible implementation of the AES encryption in CBC mode using PKCS7Padding but I haven't been able to come across much documentation. Any help provided would be greatly appreciated, also I should note that I am a student not a professional developer. Thanks.
`public class RijndaelCBC
{
private int _keySize;
private byte[] _passphrase;
public byte[] _iv { get; private set; }
private IBlockCipher blockCipher;
private PaddedBufferedBlockCipher aesCipher;
private ParametersWithIV _param;
public RijndaelCBC(int KeySize, string Passphrase)
{
if (Passphrase.Length < KeySize / 8)
Passphrase = Passphrase.PadRight(KeySize / 8, '0');
if (Passphrase.Length > KeySize)
Passphrase = Passphrase.Substring(0, KeySize / 8);
_passphrase = System.Convert.FromBase64String(Passphrase);
Array.Resize(ref _passphrase, KeySize / 8);
_keySize = KeySize;
Random rnd = new Random();
_iv = new byte[_keySize / 8];
for (int t = 0; t < _keySize / 8; t++)
rnd.Next();
rnd.NextBytes(_iv);
if (_keySize != 128 && _keySize != 192 && _keySize != 256)
throw new Exception(string.Format("Invalid key size of {0} provided, cannot continue with the process.", _keySize));
}
public RijndaelCBC(int KeySize, string Passphrase, byte[] iv)
{
if (Passphrase.Length < KeySize / 8)
Passphrase = Passphrase.PadRight(KeySize / 8, '0');
if (Passphrase.Length > KeySize)
Passphrase = Passphrase.Substring(0, KeySize / 8);
_passphrase = System.Convert.FromBase64String(Passphrase);
Array.Resize(ref _passphrase, KeySize / 8);
_keySize = KeySize;
_iv = iv;
if (_keySize != 128 && _keySize != 192 && _keySize != 256)
throw new Exception(string.Format("Invalid key size of {0} provided, cannot continue with the process.", _keySize));
}
public byte[] Encrypt(byte[] data)
{
try
{
blockCipher = new CbcBlockCipher(new RijndaelEngine(_keySize));
_param = new ParametersWithIV(new KeyParameter(_passphrase), _iv);
blockCipher.Init(true, _param);
aesCipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
byte[] cipherTextBlock = null;
int blockSize = aesCipher.GetBlockSize();
List<byte> output = new List<byte>();
int outputLen = 0;
int chunkPosition = 0;
for (chunkPosition = 0; chunkPosition < data.Length; chunkPosition += blockSize)
{
byte[] dataToProcess = new byte[blockSize];
int chunkSize = (data.Length - chunkPosition) < blockSize ? (data.Length - chunkPosition) : blockSize;
Buffer.BlockCopy(data, chunkPosition, dataToProcess, 0, chunkSize);
cipherTextBlock = new byte[blockSize];
outputLen = aesCipher.ProcessBytes(dataToProcess, 0, chunkSize, cipherTextBlock, 0);
output.AddRange(cipherTextBlock);
}
try
{
if(chunkPosition < data.Length &&
chunkPosition + blockSize > data.Length)
{
byte[] dataToProcess = new byte[blockSize];
int chunkSize = (chunkPosition + blockSize) - data.Length;
Buffer.BlockCopy(data, chunkPosition, dataToProcess, 0, chunkSize);
aesCipher.DoFinal(cipherTextBlock, 0);
output.AddRange(cipherTextBlock);
}
}
catch (CryptoException ex)
{}
return output.ToArray();
}
catch (System.Exception ex)
{ }
return null;
}
public byte[] Decrypt(byte[] data)
{
try
{
blockCipher = new CbcBlockCipher(new RijndaelEngine(_keySize));
_param = new ParametersWithIV(new KeyParameter(_passphrase), _iv);
blockCipher.Init(false, _param);
aesCipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
byte[] cipherTextBlock = null;
int blockSize = aesCipher.GetBlockSize();
List<byte> output = new List<byte>();
int outputLen = 0;
int chunkPosition = 0;
for (chunkPosition = 0; chunkPosition < data.Length; chunkPosition += blockSize)
{
byte[] dataToProcess = new byte[blockSize];
int chunkSize = (data.Length - chunkPosition) < blockSize ? (data.Length - chunkPosition) : blockSize;
Buffer.BlockCopy(data, chunkPosition, dataToProcess, 0, chunkSize);
cipherTextBlock = new byte[blockSize];
outputLen = aesCipher.ProcessBytes(dataToProcess, 0, chunkSize, cipherTextBlock, 0);
output.AddRange(cipherTextBlock);
}
try
{
if (chunkPosition < data.Length &&
chunkPosition + blockSize > data.Length)
{
byte[] dataToProcess = new byte[blockSize];
int chunkSize = (chunkPosition + blockSize) - data.Length;
Buffer.BlockCopy(data, chunkPosition, dataToProcess, 0, chunkSize);
aesCipher.DoFinal(cipherTextBlock, 0);
output.AddRange(cipherTextBlock);
}
}
catch (CryptoException ex)
{ }
return output.ToArray();
}
catch (System.Exception ex)
{ }
return null;
}
}`
Example of output: beginning of data should be:
Production Version Releases
But Ends up as: [¨dZJÊ)uól)ȱýº—ÑÚ~VE’·ðúœ×ñð ersion Releases
and end of data should be: for such products, Intel assumes no liability whatsoever, and Intel disclaims any express or implied warranty, relating to sale and/or use of Intel products, including liability or warranties relating to fitness for a particular purpose, merchantability or infringement of any patent, copyright or other intellectual property right. Intel products are not intended for use in medical, lifesaving, or life-sustaining applications.
but ends up as: for such products, Intel assumes no liability whatsoever, and Intel disclaims any express or implied warranty, relating to sale and/or use of Intel products, including liability or warran
I was trying to encrypt and decrypt an example however at the end data is lost and at the beginning the data isn't decrypted properly, but the rest of the file 52KB was perfect.