user81993
user81993

Reputation: 6613

Some bytes missing or added after encrypting/decrypting with RijndaelManaged

Here is my test code:

    Dim bah As New System.Security.Cryptography.RijndaelManaged
    bah.Mode = Security.Cryptography.CipherMode.CBC
    bah.Padding = Security.Cryptography.PaddingMode.ISO10126
    bah.KeySize = 128
    bah.BlockSize = 128
    bah.FeedbackSize = 128
    bah.Key = Key
    bah.IV = {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}

    Dim Encryptor = bah.CreateEncryptor()
    Dim Decryptor = bah.CreateDecryptor()


    Dim EncryptedBuffer(1023) As Byte
    Dim encLen As Integer = Encryptor.TransformBlock(Data, 0, 256, EncryptedBuffer, 0)
    Dim DecryptedBuffer(1023) As Byte
    Dim decLen As Integer = Decryptor.TransformBlock(EncryptedBuffer, 0, encLen, DecryptedBuffer, 0)

    Dim fbEncryptedBuffer() As Byte = Encryptor.TransformFinalBlock(Data, 0, Data.Count)
    Dim fbDecryptedBuffer() As Byte = Decryptor.TransformFinalBlock(fbEncryptedBuffer, 0, fbEncryptedBuffer.Count)

the "Data" is a 512 byte array that counts from 0 to 255 twice. The IV and Key are hardcoded values for sake of simplicity.

Anyways, there are 2 results produced with this.

First, the DecryptedBuffer starts out allright going 0, 1, 2, 3 etc but stops short at 239 or always 17 bytes less than what it should be no matter how many bytes i specify for input.

Second, fbDecryptedBuffer successfully gets the whole thing but its padded at the front by 16 seemingly random bytes.

Is this normal? I don't understand why either is happening and MSDN isn't exactly helpful on the matter. Also why are there 2 methods for transforming a block? Are they supposed to be used in conjunction? Or is one for processing in chunks while the other is for processing the whole thing?

EDIT: Oh, it actually seems the 2 results are very much connected. By removing the code that uses TransformBlock method, the TransformFinalBlock code works fine. It seems as if 16 bytes get stuck in the decryptor somehow and are then piled on the final transform call.

Upvotes: 1

Views: 148

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127563

The problem you are having is you are misusing TrasnformBlock, If you where working with just a stream think of TransformBlock as a call to Stream.Read( or Stream.Write(. Where TransformFinalBlock is like calling Stream.Read( or Stream.Write( followed by a Stream.Close()

The reason for the two functions is sometimes you want to start encrypting or decrypting your data before you have received all of your source data. You must however always call TransformFinalBlock at the end, but you can call it with 0 as the length. That is why your first part of your example did not work, you never called TransformFinalBlock to write the last bit of data out.

However, .NET provides a wrapper to make it easy for you. Instead of working with ICryptoTransform objects use a CryptoStream instead, it manages the complex under layers for you. You just get to treat it like you would any other stream. See the code snippet for examples how to use it.

Upvotes: 1

Related Questions