Reputation: 6613
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
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