我正在尝试使用 bouncycastle 库加密和解密数据,在解密数据后,数据的第一个信息块已损坏,就好像它未能成功解密并且最后一个块完全丢失一样。我是 bouncycastle 库的新手,我一直在互联网上搜索,试图使用 PKCS7Padding 在 CBC 模式下找到 AES 加密的合理实现,但我无法找到太多文档。提供的任何帮助将不胜感激,我还要注意我是学生而不是专业开发人员。谢谢。
`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;
}
}`
输出示例:数据的开头应该是:
生产版本发布
但最终结果为: [¨dZJÊ)uól)ȱýº—ÑÚ~VE'·ðúœ×ñð ersion Releases
并且数据结尾应为: 对于此类产品,英特尔不承担任何责任,并且英特尔不承担与英特尔产品的销售和/或使用相关的任何明示或暗示的保证,包括与特定用途的适用性、适销性相关的责任或保证或侵犯任何专利、版权或其他知识产权。英特尔产品不适用于医疗、救生或维持生命的应用。
但最终结果为: 对于此类产品,英特尔不承担任何责任,并且英特尔不承担与英特尔产品的销售和/或使用相关的任何明示或暗示的保证,包括责任或保证
我试图加密和解密一个例子,但是最后数据丢失了,一开始数据没有正确解密,但文件的其余部分 52KB 是完美的。