代码之家  ›  专栏  ›  技术社区  ›  J. Polfer

Rijndael管理的:纯文本长度偏差

  •  3
  • J. Polfer  · 技术社区  · 14 年前

    我花了一些时间学习如何在.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作为值吗?


    编辑:我想我需要想出一种新的方法来加密字节数组,而不是使用流作者。一个勇敢的人 MSDN page 显示这将首先执行某种类型的字符串转换,我不希望这样做。有什么想法吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Sani Huttunen    14 年前

    在这种情况下,您不能也不需要使用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