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リリース
データの終わりは次のとおり です。そのような製品について、インテルは一切の責任を負わず、インテル製品の販売および/または使用に関連する明示または黙示の保証を否認します。これには、特定の目的への適合性、商品性に関連する責任または保証が含まれます。または、特許、著作権、またはその他の知的財産権の侵害。インテル製品は、医療、救命、または生命維持の用途での使用を目的としていません。
ただし、最終的には次 のようになります。そのような製品については、インテルは一切の責任を負わず、インテルは、責任または保証を含む、インテル製品の販売および/または使用に関連する明示または黙示の保証を否認します。
私は例を暗号化して復号化しようとしましたが、最後にデータが失われ、最初にデータが適切に復号化されませんでしたが、ファイルの残りの部分52KBは完璧でした。