【问题标题】:C# AES encryption: Starting/Ending space throw CryptographicException: 'The input data is not a complete blockC# AES 加密:开始/结束空间抛出 CryptographicException:'输入数据不是完整块
【发布时间】:2018-03-11 17:12:21
【问题描述】:

我正在使用 C# 研究 AES,并编写了一些代码来加密字符串。 起初,它会在下面抛出异常。

System.Security.Cryptography.CryptographicException: '填充无效,无法移除。'

我通过将加密/解密的填充模式设置为“无”解决了这个问题。

然后,我在要加密的字符串之前/之后放置了一些空格。然后,我得到以下异常。

System.Security.Cryptography.CryptographicException:'输入数据不是一个完整的块。'

所以,我删除了用于加密的填充设置。然后,一切看起来都很好。

我的问题是

  1. 为什么我必须指定填充模式?
  2. 开始/结束空格的字符串转换为字节数组后,我看到的只是一个字节数组。一堆数字。加密/解密是否关心字符串之前/之后的字节类型?
  3. 为什么“设置填充模式无仅用于解密”有效?我期望加密/解密的对称填充设置。对于 AES,加密/解密的默认填充“PKCS7”。

提前致谢。

public void ByteEncryption()
{
    byte[] key = new byte[16];
    byte[] iv = new byte[16];

    for (int ii = 0; ii < 16; ii++)
    {
        key[ii] = (byte)ii;
        iv[ii] = (byte)ii;
    }

    string str_data = "   This is a string to be encrypted    ";
    byte[] data = Encoding.Unicode.GetBytes(str_data);
    byte[] encrypted = EncryptMemory(data, key, iv);
    foreach(byte b in encrypted)
        Console.WriteLine(b);

    string str_encrypted = Encoding.Unicode.GetString(encrypted);
    Console.Write("Encrypted:");
    Console.WriteLine(str_encrypted);

    byte[] decrypted = DecryptMemory(encrypted, key, iv);
    string str_decrypted = Encoding.Unicode.GetString(decrypted);
    Console.Write("---");
    Console.Write(str_decrypted);
    Console.WriteLine("---");
}

byte[] EncryptMemory(byte[] data, byte[] key, byte[] iv)
{
    using (SymmetricAlgorithm algorithm = Aes.Create())
    {
        algorithm.Padding = PaddingMode.None; // Throw exception                
        using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
        {
                return Crypt(data, encryptor);
        }
    }
}

byte[] DecryptMemory(byte[] data, byte[] key, byte[] iv)
{
    using (SymmetricAlgorithm algorithm = Aes.Create())
    {
        algorithm.Padding = PaddingMode.None;
        using (ICryptoTransform decryptor = algorithm.CreateDecryptor(key, iv))
        {
            return Crypt(data, decryptor);
        }
    }
}

byte[] Crypt(byte[] data, ICryptoTransform cryptor)
{
    using (MemoryStream memory = new MemoryStream())
    using (CryptoStream stream = new CryptoStream(memory, cryptor, CryptoStreamM    ode.Write))
    {
        stream.Write(data, 0, data.Length);
        return memory.ToArray();
    }
}

【问题讨论】:

    标签: c# exception aes padding space


    【解决方案1】:

    来自link,在阅读了下面cadrell0的评论后,

    很好地调用 Dispose。我在处理 CryptoStream 之前调用了 ms.ToArray()。将那条线移到 using 之外为我修复了它

    我解决了这个问题。这已经折磨了我2天。 回答我的问题,所有的误解都来自我加密的字符串的长度。通过插入随机数量的字符,输入的不带特殊字符的字符串长度意外地正好是16的倍数; unicode 的大小为 16 位。没有特殊字符的原始字符串不需要填充,因为它已经是 16 的倍数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      相关资源
      最近更新 更多