Я пытался узнать больше о System.Security.Cryptography в c# с онлайн-документами и примерами. До сих пор я был в состоянии успешно зашифровать и расшифровать как текст, так и файлы; Тем не менее, я получил исключение при попытке расшифровать с неправильным ключом.
Blockquote System.Security.Cryptography.CryptographicException: 'Заполнение является недопустимым и не может быть удалено.'
Шифрование
private static byte[] EncryptData(SymmetricAlgorithms symmetricAlgorithm, byte[] inputBytes, byte[] key)
{
byte[] output;
using (SymmetricAlgorithm algorithm = SymmetricAlgorithmFactory(symmetricAlgorithm))
{
byte[] encrypted;
byte[] salt = new byte[PBKDF2_SaltBytes];
int maxKeySize = GetLegalKeySizes(algorithm).Max();
_rng.GetBytes(salt); //
using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(key, salt, PBKDF2_Iterations))
{
algorithm.Key = pbkdf2.GetBytes(maxKeySize);
}
//algorithm.Padding = PaddingMode.PKCS7;
using (ICryptoTransform cryptoTransform = algorithm.CreateEncryptor())
{
using (MemoryStream inputStream = new MemoryStream(inputBytes), transformedStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(inputStream, cryptoTransform, CryptoStreamMode.Read))
{
cryptoStream.CopyTo(transformedStream);
}
encrypted = transformedStream.ToArray();
}
}
output = new byte[salt.Length + algorithm.IV.Length + encrypted.Length];
Buffer.BlockCopy(salt, 0, output, 0, salt.Length);
Buffer.BlockCopy(algorithm.IV, 0, output, salt.Length, algorithm.IV.Length);
Buffer.BlockCopy(encrypted, 0, output, salt.Length + algorithm.IV.Length, encrypted.Length);
}
return output;
}
Дешифрование
private static byte[] DecryptData(SymmetricAlgorithms symmetricAlgorithm, byte[] inputBytes, byte[] key)
{
using (SymmetricAlgorithm algorithm = SymmetricAlgorithmFactory(symmetricAlgorithm))
{
byte[] salt = new byte[PBKDF2_SaltBytes];
byte[] iv = new byte[algorithm.IV.Length];
byte[] encryptedData = new byte[inputBytes.Length - salt.Length - iv.Length];
int maxKeySize = GetLegalKeySizes(algorithm).Max();
Buffer.BlockCopy(inputBytes, 0, salt, 0, salt.Length);
Buffer.BlockCopy(inputBytes, salt.Length, iv, 0, iv.Length);
Buffer.BlockCopy(inputBytes, salt.Length + iv.Length, encryptedData, 0, encryptedData.Length);
algorithm.IV = iv;
//algorithm.Padding = PaddingMode.PKCS7;
using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(key, salt, PBKDF2_Iterations))
{
algorithm.Key = pbkdf2.GetBytes(maxKeySize);
}
using(ICryptoTransform cryptoTransform = algorithm.CreateDecryptor())
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(encryptedData, 0, encryptedData.Length);
cryptoStream.FlushFinalBlock();
}
return memoryStream.ToArray();
}
}
}
}
SymmetricAlgorithmFactory возвращает экземпляр SymmetricAlgorithm
private static SymmetricAlgorithm SymmetricAlgorithmFactory(SymmetricAlgorithms symmetricAlgorithm)
{
switch (symmetricAlgorithm)
{
case SymmetricAlgorithms.AES:
return new AesCryptoServiceProvider();
case SymmetricAlgorithms.DES:
return new DESCryptoServiceProvider();
case SymmetricAlgorithms.RC2:
return new RC2CryptoServiceProvider();
case SymmetricAlgorithms.Rijndael:
return new RijndaelManaged();
case SymmetricAlgorithms.TripleDES:
return new TripleDESCryptoServiceProvider();
default:
throw new Exception("The provided Symmetric algorithm is not supported.");
}
}
public enum SymmetricAlgorithms
{
AES,
DES,
RC2,
Rijndael,
TripleDES
}
Дополнительные свойства класса
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
private const int PBKDF2_SaltBytes = 8; //PBKDF2 recommends 64 bits minimum. 64 / 8 = 8 bytes
private const int PBKDF2_Iterations = 10000;
private static Encoding encoding = Encoding.UTF32;
Используя AES для тестирования, я затем попытался изменить свойство padding и получил несколько разных сообщений
PaddingMode.None
- Метод шифрования вызвал исключение
Blockquote System.Security.Cryptography.CryptographicException: 'Входные данные не являются полным блоком.'
PaddingMode.PKCS7 + PaddingMode.ANSIX923 + PaddingMode.ISO10126
- метод дешифрования сгенерировал исключение
Blockquote System.Security.Cryptography.CryptographicException: 'Заполнение недействительно и не может быть удален. '
PaddingMode.Zeros
- Кажется, это работает с правильным и неправильным ключом
Кто-нибудь сможет Помогите понять, как работают отступы и почему некоторые режимы не работают? Будет ли это ситуация, когда для каждого из разных алгоритмов Symmetri c потребуется разное заполнение?