【问题标题】:Rijndael managed: plaintext length detctionRijndaelmanaged:明文长度检测
【发布时间】:2010-05-28 00:23:11
【问题描述】:

我正在花一些时间学习如何在 .NET 中使用 RijndaelManaged 库,并开发了以下函数来测试加密文本,并对 MSDN 库稍作修改:

Function encryptBytesToBytes_AES(ByVal plainText As Byte(), ByVal Key() As Byte, ByVal IV() As Byte) As Byte()
        ' Check arguments.
        If plainText Is Nothing OrElse plainText.Length <= 0 Then
            Throw New ArgumentNullException("plainText")
        End If
        If Key Is Nothing OrElse Key.Length <= 0 Then
            Throw New ArgumentNullException("Key")
        End If
        If IV Is Nothing OrElse IV.Length <= 0 Then
            Throw New ArgumentNullException("IV")
        End If

        ' Declare the RijndaelManaged object
        ' used to encrypt the data.
        Dim aesAlg As RijndaelManaged = Nothing

        ' Declare the stream used to encrypt to an in memory
        ' array of bytes.
        Dim msEncrypt As MemoryStream = Nothing

        Try
            ' Create a RijndaelManaged object
            ' with the specified key and IV.
            aesAlg = New RijndaelManaged()
            aesAlg.BlockSize = 128
            aesAlg.KeySize = 128
            aesAlg.Mode = CipherMode.ECB
            aesAlg.Padding = PaddingMode.None
            aesAlg.Key = Key
            aesAlg.IV = IV

                ' Create a decrytor to perform the stream transform.
                Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)

                ' Create the streams used for encryption.
                msEncrypt = New MemoryStream()
                Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                    Using swEncrypt As New StreamWriter(csEncrypt)

                        'Write all data to the stream.
                        swEncrypt.Write(plainText)
                    End Using
                End Using

        Finally
            ' Clear the RijndaelManaged object.
            If Not (aesAlg Is Nothing) Then
                aesAlg.Clear()
            End If
        End Try
        ' Return the encrypted bytes from the memory stream.
        Return msEncrypt.ToArray()

    End Function

这是我调用 encryptBytesToBytes_AES() 的实际代码:

Private Sub btnEncrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEncrypt.Click
    Dim bZeroKey As Byte() = {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0}
    PrintBytesToRTF(encryptBytesToBytes_AES(bZeroKey, bZeroKey, bZeroKey))
End Sub

但是,我在 swEncrypt.Write(plainText) 上引发了一个异常,指出“要加密的数据长度无效。”

但是,我知道我的密钥、iv 和明文的大小是 16 字节 == 128 位 == aesAlg.BlockSize。 为什么会抛出这个异常? 是不是因为 StreamWriter 试图创建一个字符串(表面上带有某种编码)并且它不喜欢 &H0 作为值?


编辑:我想我需要想出一种新的方法来加密字节数组,而不是使用 StreamWriter。 MSDN page 上的一个 gander 表明这将首先进行某种字符串转换,这是我不想要的。有什么想法吗?

【问题讨论】:

  • 也许它反对,因为您要求 ECB 模式,但包括 IV(ECB 中未使​​用)?
  • @Jerry - 会尝试,因为您对 IV 的看法是正确的。
  • @Jerry - 不,仍然会发生,即使我将代码更改为不设置 IV。但观察力很好。
  • 在使用 ECB 模式时设置 IV 没有影响。该算法只是忽略它。

标签: rijndaelmanaged


【解决方案1】:

在这种情况下,您不能也不需要使用 StreamWriter。
StreamWriter 不接受 Byte() 作为参数。

您可以将加密功能修改为以下内容:

Function encryptBytesToBytes_AES(ByVal plainText As Byte(), ByVal Key() As Byte, ByVal IV() As Byte) As Byte()
    ' Check arguments.'
    If plainText Is Nothing OrElse plainText.Length <= 0 Then
        Throw New ArgumentNullException("plainText")
    End If
    If Key Is Nothing OrElse Key.Length <= 0 Then
        Throw New ArgumentNullException("Key")
    End If
    If IV Is Nothing OrElse IV.Length <= 0 Then
        Throw New ArgumentNullException("IV")
    End If

    ' Declare the RijndaelManaged object'
    ' used to encrypt the data.'
    Dim aesAlg As RijndaelManaged = Nothing

    Dim encryptedData As Byte()

    Try
        ' Create a RijndaelManaged object'
        ' with the specified key and IV.'
        aesAlg = New RijndaelManaged()
        aesAlg.BlockSize = 128
        aesAlg.KeySize = 128
        aesAlg.Mode = CipherMode.ECB
        aesAlg.Padding = PaddingMode.None
        aesAlg.Key = Key
        aesAlg.IV = IV

        ' Create a decrytor to perform the stream transform.'
        Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor()

        ' Create the streams used for encryption.'
        Using msEncrypt As New MemoryStream()

            Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                csEncrypt.Write(plainText, 0, plainText.Length)
                csEncrypt.FlushFinalBlock()
            End Using
            encryptedData = msEncrypt.ToArray()
        End Using

    Finally
        ' Clear the RijndaelManaged object.'
        If Not (aesAlg Is Nothing) Then
            aesAlg.Clear()
        End If
    End Try
    ' Return the encrypted bytes from the memory stream.'
    Return encryptedData
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    相关资源
    最近更新 更多