【问题标题】:error on Decrypting AES. The input data in not a complete block. vb.net解密 AES 时出错。输入数据不是一个完整的块。 VB.net
【发布时间】:2018-07-16 12:15:52
【问题描述】:

美好的一天。 我正在使用 AES 加密文本,然后将加密的字节保存到 txt 文件中。

--

form1.frm中btnencrypt的代码

Dim aes_CryptoTransform As ICryptoTransform = AesCryptoServiceProvider.Create.CreateEncryptor(aesKeySet.Key, aesKeySet.IV)
Dim textBytes() As Byte = System.Text.Encoding.ASCII.GetBytes(rtb_plaintext.Text)

Dim encrypted() As Byte
using msEncrypt As New MemoryStream()
     using csEncrypt As New CryptoStream(textBytes, aes_CryptoTransform, CryptoStreamMode.write)
          using textStream as New StreamWriter(csEncrypt) 
               swEncrypt.Write(plainText)
          End Using
          encrypted = msEncrypt.ToArray()
          csEncrypt.close()
     End Using
End Using

dim textDirectoryPath as String = "C:\encryptText.text"
using textFilestream as new Filestream(textDirectoryPath, filemode.create)
     textFilestream.write(encrypted, 0, encrypted.length)
     textFilestream.close()
end using

--

form2.frm中btnDecrypt的代码

Dim aes_CryptoTransform As ICryptoTransform = AesCryptoServiceProvider.Create.CreateEncryptor(aesKeySet.Key, aesKeySet.IV)

Dim textBytesToDecrypt() As Byte = File.readAllBytes("C:\encryptText.text")
dim plainText as string = nothing

using msEncrypt As New MemoryStream(textBytesToDecrypt)
     using csEncrypt As New CryptoStream(textBytes, aes_CryptoTransform, CryptoStreamMode.read)
          using textStream as New StreamReader(csEncrypt) 
              plainText = textStream.readToEnd()
          End Using
          csEncrypt.close()
     End Using
End Using

-- 如果我单击解密按钮,我会收到一条错误消息,提示“输入数据不是完整的块” 我似乎做错了什么?

【问题讨论】:

  • 我认为这里还有其他错误。您应该将 msEncrypt 作为第一个参数传递给 CryptoStream 构造函数,否则 msEncrypt 永远不会向其中写入任何内容。
  • 我也没有看到文件作为截断文件打开。如果它已经存在,数据将被追加到文件的末尾。
  • 使用 File.ReadAllBytes 而不是 File.WriteAllBytes 似乎有点不对称。但首先要检查的是你认为你写了多少字节,你读了多少。 FWIW,正确答案将是 16 的倍数。

标签: vb.net aes


【解决方案1】:

我想你忘记给swEncrypt.FlushFinalBlock()打电话了。我没有太多的 VB 经验,但错误意味着加密数据没有填充到完整的块大小。我的 C# 代码看起来和你的很像,只是我在写字节然后调用 FlushFinalBlock()

参见 C# 中的示例:

private IEncryptionResponse Encrypt(byte[] data, IKey key)
{
    try
    { 
        using (var symmetricAlgorithm = new AesCryptoServiceProvider())
        {
            symmetricAlgorithm.GenerateIV();
            byte[] iv = symmetricAlgorithm.IV;

            using (var msEncrypt = new MemoryStream())
            {
                using (var encryptor = symmetricAlgorithm.CreateEncryptor(key.RawKey, iv))
                {
                    using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        try
                        {
                            csEncrypt.Write(data, 0, data.Length);
                            csEncrypt.FlushFinalBlock();
                            var encryptedBytes = msEncrypt.ToArray();

                            return Convert.ToBase64String(iv.Add(encryptedBytes));
                        }
                        finally
                        {
                           symmetricAlgorithm.Clear();
                        }
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        throw new EncryptionException("Encryption error", e);
    }

}

【讨论】:

  • 使用using,资源应该会自动关闭。而如果是自动关闭的,应该是自动冲水的。如果它被自动刷新,我会假设 FlushFinalBlock 被调用作为结果。
  • 问题中使用的 StreamReader ctor 导致 CryptoStream 在 StreamReader 存在时被释放,因此 FlushFinalBlock 已经隐式调用。 (又名“@MaartenBodewes 是正确的”)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
相关资源
最近更新 更多