【发布时间】:2020-02-05 09:39:33
【问题描述】:
我一直在尝试通过在线文档和示例了解更多关于 c# 中的 System.Security.Cryptography 的信息。到目前为止,我已经能够成功地加密/解密文本和文件;但是,当我尝试使用不正确的密钥解密时抛出异常。
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 进行测试,然后我尝试更改填充属性并得到一些不同的消息
PaddingMode.None - 加密方法抛出异常
Blockquote System.Security.Cryptography.CryptographicException: '输入数据不是一个完整的块。'
PaddingMode.PKCS7 + PaddingMode.ANSIX923 + PaddingMode.ISO10126 - 解密方法抛出异常
Blockquote System.Security.Cryptography.CryptographicException: '填充无效,无法删除。'
PaddingMode.Zeros - 这似乎适用于正确和不正确的密钥
谁能帮助我理解填充以及为什么某些模式会失败?会不会是每个不同的对称算法都需要不同的填充?
【问题讨论】:
-
我认为我从stackoverflow.com/a/14971080/10495770 找到了答案,看起来这种行为可能在使用错误密码时发生,使用身份验证时可以检查密码是否正确
标签: c# encryption