File Encryption/Decryption problem

L

Loren

I’m trying to encrypt and decrypt a file in vb.net. I am using the
TripleDESCryptoServiceProvider encryption found in
System.Security.Cryptography. Below is the code for my Encrypt and Decrypt
functions.

While my functions read and write files the encryption/decryption is not
working properly. My test file has an original length of 66,048 bytes. My
encrypted file ends up with 66,056 bytes … 8 bytes more than my original.
When I decrypt the encrypted file the resultant file is also 66,056 bytes in
length … obviously different than the original!

I feel like I’m missing something obvious. Does anyone have any
suggestions? Thanks for your help.

Public Function EncryptFile(ByVal SourceFilename As String, ByVal
DestinationFilename As String) As Boolean

Dim fsSourceStream As System.IO.FileStream = Nothing
Dim encryptionStream As CryptoStream = Nothing
Dim fsDestinationStream As System.IO.FileStream = Nothing

Try
' Open file streams for the file reading and writing
fsSourceStream = New System.IO.FileStream(SourceFilename,
FileMode.Open, IO.FileAccess.Read)
fsDestinationStream = New
System.IO.FileStream(DestinationFilename, FileMode.Create,
IO.FileAccess.Write)

'Bytes will be encrypted by an encryption stream
encryptionStream = New CryptoStream(fsDestinationStream, _
New
TripleDESCryptoServiceProvider().CreateEncryptor(mvarKey, mvarIV),
CryptoStreamMode.Write)

mvarBufferSize = 1024
' Create buffer
Dim fileBuffer(mvarBufferSize) As Byte
Dim accumulatedBytesRead As Integer = 0
Dim bytesRead As Integer

' read the file
' Process bytes from fsSourceStream through the encryptionStream
to the fsDestinationStream.
Do
bytesRead = fsSourceStream.Read(fileBuffer, 0, mvarBufferSize)
If (bytesRead = 0) Then Exit Do
encryptionStream.Write(fileBuffer, 0, bytesRead)
accumulatedBytesRead += bytesRead
Loop

encryptionStream.FlushFinalBlock()
Return True

Catch ex As Exception
MsgBox("Exception error occurred in EncryptFile." & vbNewLine &
vbNewLine _
& ex.Message, MsgBoxStyle.OkOnly Or
MsgBoxStyle.Information)
Return False

Finally

'close streams
If encryptionStream IsNot Nothing Then
encryptionStream.Close()
End If

If fsSourceStream IsNot Nothing Then
fsSourceStream.Close()
End If

If fsDestinationStream IsNot Nothing Then
fsDestinationStream.Close()
End If

End Try

End Function

Public Function DecryptFile(ByVal SourceFilename As String, ByVal
DestinationFilename As String) As Boolean

Dim fsSourceStream As System.IO.FileStream = Nothing
Dim decryptionStream As CryptoStream = Nothing
Dim fsDestinationStream As System.IO.FileStream = Nothing

Try
' Open file streams for the file reading and writing
fsSourceStream = New System.IO.FileStream(SourceFilename,
FileMode.Open, IO.FileAccess.Read)
fsDestinationStream = New
System.IO.FileStream(DestinationFilename, FileMode.Create,
IO.FileAccess.Write)

' Process bytes through a CryptoStream.
decryptionStream = New CryptoStream(fsSourceStream, _
New
TripleDESCryptoServiceProvider().CreateEncryptor(mvarKey, mvarIV),
CryptoStreamMode.Read)

' Create buffer
mvarBufferSize = 1024
Dim fileBuffer(mvarBufferSize) As Byte
Dim accumulatedBytesRead As Integer = 0
Dim bytesRead As Integer

' read the file
' Process bytes from fsSourceStream to fsDestinationStream.
Do
bytesRead = decryptionStream.Read(fileBuffer, 0,
mvarBufferSize)
If (bytesRead = 0) Then Exit Do
fsDestinationStream.Write(fileBuffer, 0, bytesRead)
accumulatedBytesRead += bytesRead
Loop

fsDestinationStream.Flush()
Return True


Catch ex As Exception
MsgBox("Exception error occurred in DecryptFile." & vbNewLine &
vbNewLine _
& ex.Message, MsgBoxStyle.OkOnly Or
MsgBoxStyle.Information)
Return False

Finally

'close(streams)
If decryptionStream IsNot Nothing Then
decryptionStream.Close()
End If

If fsSourceStream IsNot Nothing Then
fsSourceStream.Close()
End If

If fsDestinationStream IsNot Nothing Then
fsDestinationStream.Close()
End If

End Try


End Function
 
M

Mike C#

DES-based encryption algorithms use an 8-byte block length. When you
encrypt a file using a DES-based function it rounds up to the next nearest
8-byte length. If you're sitting on an 8-byte boundary (like 66,048 bytes),
it is probably padding it up to the next 8-byte boundary. I would guess
that the length difference in the encrypted file is just an additional 8
bytes of padding added to the output by the encryption algorithm. In fact,
try it with a 66,041 to 66,047 byte file and I would expect the output to be
66,048 bytes in every case.

When you decrypt it's probably padding the end of the decrypted data with
NUL characters (character 0, or some other padding character). You should
be able to just strip off all character 0's from the end of the decrypted
data. If NUL characters on the end of the file might be important (for
instance if you're encrypting binary files) you might even consider adding
the file length as the first 4 or 8 bytes of the data you're encrypting so
you'll know exactly how much padding to strip off the end of the decrypted
data. There are other padding options, such as padding with a length
character to tell you exactly how many padding bytes were added to the end,
like this:

4e 5f 6a 12 9f 03 03 03

In this example the padding character is "03" indicating that the last three
bytes of the last 8-byte block are all padding characters. It's been a
while for me, but I believe you can set these padding options in the
TripleDESCryptoServiceProvider or other service providers.
 
L

Loren

Thanks Mike. I think that you’re correct in DES-based encryption algorithms
use an 8-byte block length. However, my problem was far more simply
corrected (I knew I couldn’t see the forest from the trees!). My error was
in my decryption function where I create my decryptionStream. The error was
that I created and “Encryptor†instead of “Decryptor†in this function.
After making that change both functions worked correctly.

Thanks for your help.
 
M

Mike C#

Loren said:
Thanks Mike. I think that you're correct in DES-based encryption
algorithms
use an 8-byte block length. However, my problem was far more simply
corrected (I knew I couldn't see the forest from the trees!). My error
was
in my decryption function where I create my decryptionStream. The error
was
that I created and "Encryptor" instead of "Decryptor" in this function.
After making that change both functions worked correctly.

Thanks for your help.

Very cool, so I guess the decryption service provider automatically strips
the extra padding when you decrypt it. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top