Dataset encryption

A

Anon

I made this class to encrypt my DataSet before saving it
to disk. So, first in the main program I write the
DataSet to XML in a MemoryStream. I pass this stream to
the E_File sub, which encrypts the stream and writes it
out to the FileStream. Now, in the D_File function, I
read the encrypted file into a FileStream, then decrypt
it into a MemoryStream, which I pass back to my DataSet
and Read the XML into the DataSet. The problem I'm
having, is somewhere I'm losing the last 2 bytes of the
file, so if my DataSet is named "NewDataSet", the end of
the file looks like </NewDataSe
I'm not sure where these two bytes are being lost at, and
if anyone could point out my blunder, I can stop beating
my head into walls and keyboards!
Below is my code for the encryption class:

Imports System
Imports System.Text
Imports System.IO
Imports System.Security
Imports System.Security.Cryptography

Public Class Perculate
Public Event Callback(ByVal Msg As String)
Public Event Bytes_Processed(ByVal Curr As Long,
ByVal Total As Long)
Protected IV() As Byte = New Byte() {0, 0, 0, 0, 0,
0, 0, 0}

Public Function D_File(ByVal InFile As String, ByVal
key As String) As Stream
Dim fin As New FileStream(InFile, FileMode.Open,
FileAccess.Read)
Dim _ms As New MemoryStream(fin.Length)

Dim bin(100) As Byte
Dim redlin As Long = 0
Dim totlen As Long = fin.Length
Dim len As Integer

If key.Length < 24 Then key = New String("0", 24 -
key.Length) & key

Try
Dim tdes As New TripleDESCryptoServiceProvider
()
Dim decStream As New CryptoStream(_ms, _
tdes.CreateDecryptor
(Text.ASCIIEncoding.ASCII.GetBytes(key), _
IV), _
CryptoStreamMode.Write)
RaiseEvent Callback("Decrypting")

fin.Position = 0

Do
len = fin.Read(bin, 0, bin.Length)
decStream.Write(bin, 0, len)
redlin += len
RaiseEvent Bytes_Processed(redlin, totlen)
If len = 0 Then Exit Do
Loop
Return _ms
Catch ex As CryptographicException
RaiseEvent Callback(ex.Message)
End Try
End Function

Public Sub E_File(ByVal InData As Stream, ByVal
Outfile As String, ByVal Key As String)
If File.Exists(Outfile) Then File.Delete(Outfile)
Dim fout As New FileStream(Outfile,
FileMode.CreateNew, FileAccess.Write)

fout.SetLength(0)

Dim bin(100) As Byte
Dim redlin As Long = 0
Dim totlen As Long = InData.Length + 2
Dim len As Integer
Dim hByte() As Byte = ASCIIEncoding.ASCII.GetBytes
("<?xml version=" & Chr(34) & "1.0" & Chr(34) & "
standalone=" & Chr(34) & "yes" & Chr(34) & "?>" & vbCrLf)

If Key.Length > 24 Then
RaiseEvent Callback("Key must be 24 or less
characters!")
Exit Sub
ElseIf Key.Length < 6 Then
RaiseEvent Callback("Key must be 6 or more
characters!")
Exit Sub
End If
If Key.Length < 24 Then Key = New String("0", 24 -
Key.Length) & Key
Try
Dim tdes As New TripleDESCryptoServiceProvider
()
If Not tdes.IsWeakKey
(Text.ASCIIEncoding.ASCII.GetBytes(Key)) Then
Dim encStream As New CryptoStream(fout, _
tdes.CreateEncryptor
(Text.ASCIIEncoding.ASCII.GetBytes(Key), _
IV),
_
CryptoStreamMode.Write)

RaiseEvent Callback("Encrypting")

InData.Position = 0
'Force it to write out the XML header info
encStream.Write(hByte, 0, hByte.Length)
Do
len = InData.Read(bin, 0, bin.Length)
encStream.Write(bin, 0, len)
redlin += len
RaiseEvent Bytes_Processed(redlin,
totlen)
If len = 0 Then Exit Do
Loop
encStream.Close()
Else
RaiseEvent Callback("The key is
weak!!!!!")
End If
Catch ex As CryptographicException
RaiseEvent Callback(ex.Message)
End Try
End Sub
End Class

Thanks.
 
G

Guest

Here's my file decryption routines, they're very similar... Take a look at
the documentation for SymmetricAlgorithm.BlockSize, I think your problem lies
here..

' <summary>
' Purpose: Decrypts a file
' </summary>
' <param name="FileToDecrypt">This is the encrypted file that will be
read from.</param>
' <param name="DecryptedFile">This is the file that will be
decrypted.</param>
Public Sub DecryptFile(ByVal strFileToDecrypt As String, _
ByVal strDecryptedFile As String)

'Create the file streams to handle the input and output files.
Dim fin As New System.IO.FileStream(strFileToDecrypt,
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim fout As New System.IO.FileStream(strDecryptedFile,
System.IO.FileMode.OpenOrCreate, _
System.IO.FileAccess.Write)
fout.SetLength(0)

'Create variables to help with read and write.
Dim key() As Byte = GetLegalKey(strKey)
Dim bin(4096) As Byte 'This is intermediate storage for the
encryption.
Dim rdlen As Long = 8 'This is the total number of bytes written.
Dim totlen As Long = fin.Length 'Total length of the input file.
Dim len As Integer 'This is the number of bytes to be written at a
time.
Dim des As New System.Security.Cryptography.DESCryptoServiceProvider()
Dim encStream As New System.Security.Cryptography.CryptoStream(fout, _
des.CreateDecryptor(key, key),
System.Security.Cryptography.CryptoStreamMode.Write)

Console.WriteLine("Encrypting...")

'Read from the input file, then encrypt and write to the output file.
While rdlen < totlen
len = fin.Read(bin, 0, 4096)
encStream.Write(bin, 0, len)
rdlen = Convert.ToInt32(rdlen + len / des.BlockSize *
des.BlockSize)
Console.WriteLine("Processed {0} bytes, {1} bytes total", len, _
rdlen)
End While

encStream.Close()
End Sub

' <summary>
' Purpose: Encrypts a file
' </summary>
' <param name="FileToEncrypt">This is the file that will be read
from.</param>
' <param name="EncryptedFile">This is the file that will be
encrypted.</param>
Public Sub EncryptFile(ByVal strFileToEncrypt As String, _
ByVal strEncryptedFile As String)

'Create the file streams to handle the input and output files.
Dim fin As New System.IO.FileStream(strFileToEncrypt,
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim fout As New System.IO.FileStream(strEncryptedFile,
System.IO.FileMode.OpenOrCreate, _
System.IO.FileAccess.Write)
fout.SetLength(0)

'Create variables to help with read and write.
Dim key() As Byte = GetLegalKey(strKey)
Dim bin(4096) As Byte 'This is intermediate storage for the
encryption.
Dim rdlen As Long = 8 'This is the total number of bytes written.
Dim totlen As Long = fin.Length 'Total length of the input file.
Dim len As Integer 'This is the number of bytes to be written at a
time.
Dim des As New System.Security.Cryptography.DESCryptoServiceProvider()
Dim encStream As New System.Security.Cryptography.CryptoStream(fout, _
des.CreateEncryptor(key, key),
System.Security.Cryptography.CryptoStreamMode.Write)

Console.WriteLine("Encrypting...")

'Read from the input file, then encrypt and write to the output file.
While rdlen < totlen
len = fin.Read(bin, 0, 4096)
encStream.Write(bin, 0, len)
rdlen = Convert.ToInt32(rdlen + len / des.BlockSize *
des.BlockSize)
Console.WriteLine("Processed {0} bytes, {1} bytes total", len, _
rdlen)
End While

encStream.Close()
fout.Close()

End Sub
 
A

Anon

-----Original Message-----
Here's my file decryption routines, they're very similar... Take a look at
the documentation for SymmetricAlgorithm.BlockSize, I think your problem lies
here..

' <summary>
' Purpose: Decrypts a file
' </summary>
' <param name="FileToDecrypt">This is the encrypted file that will be
read from.</param>
' <param name="DecryptedFile">This is the file that will be
decrypted.</param>
Public Sub DecryptFile(ByVal strFileToDecrypt As String, _
ByVal strDecryptedFile As String)

'Create the file streams to handle the input and output files.
Dim fin As New System.IO.FileStream (strFileToDecrypt,
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim fout As New System.IO.FileStream (strDecryptedFile,
System.IO.FileMode.OpenOrCreate, _
System.IO.FileAccess.Write)
fout.SetLength(0)

'Create variables to help with read and write.
Dim key() As Byte = GetLegalKey(strKey)
Dim bin(4096) As Byte 'This is intermediate storage for the
encryption.
Dim rdlen As Long = 8 'This is the total number of bytes written.
Dim totlen As Long = fin.Length 'Total length of the input file.
Dim len As Integer 'This is the number of bytes to be written at a
time.
Dim des As New System.Security.Cryptography.DESCryptoServiceProvider()
Dim encStream As New
System.Security.Cryptography.CryptoStream(fout, _
des.CreateDecryptor(key, key),
System.Security.Cryptography.CryptoStreamMode.Write)

Console.WriteLine("Encrypting...")

'Read from the input file, then encrypt and write to the output file.
While rdlen < totlen
len = fin.Read(bin, 0, 4096)
encStream.Write(bin, 0, len)
rdlen = Convert.ToInt32(rdlen + len / des.BlockSize *
des.BlockSize)
Console.WriteLine("Processed {0} bytes, {1} bytes total", len, _
rdlen)
End While

encStream.Close()
End Sub

' <summary>
' Purpose: Encrypts a file
' </summary>
' <param name="FileToEncrypt">This is the file that will be read
from.</param>
' <param name="EncryptedFile">This is the file that will be
encrypted.</param>
Public Sub EncryptFile(ByVal strFileToEncrypt As String, _
ByVal strEncryptedFile As String)

'Create the file streams to handle the input and output files.
Dim fin As New System.IO.FileStream (strFileToEncrypt,
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim fout As New System.IO.FileStream (strEncryptedFile,
System.IO.FileMode.OpenOrCreate, _
System.IO.FileAccess.Write)
fout.SetLength(0)

'Create variables to help with read and write.
Dim key() As Byte = GetLegalKey(strKey)
Dim bin(4096) As Byte 'This is intermediate storage for the
encryption.
Dim rdlen As Long = 8 'This is the total number of bytes written.
Dim totlen As Long = fin.Length 'Total length of the input file.
Dim len As Integer 'This is the number of bytes to be written at a
time.
Dim des As New System.Security.Cryptography.DESCryptoServiceProvider()
Dim encStream As New
System.Security.Cryptography.CryptoStream(fout, _
des.CreateEncryptor(key, key),
System.Security.Cryptography.CryptoStreamMode.Write)

Console.WriteLine("Encrypting...")

'Read from the input file, then encrypt and write to the output file.
While rdlen < totlen
len = fin.Read(bin, 0, 4096)
encStream.Write(bin, 0, len)
rdlen = Convert.ToInt32(rdlen + len / des.BlockSize *
des.BlockSize)
Console.WriteLine("Processed {0} bytes, {1} bytes total", len, _
rdlen)
End While

encStream.Close()
fout.Close()

End Sub

:
Thank you, I will try this tonight and post the results
in the morning.
 
A

Anon

Well, I tried Aliens suggestion, and still no luck. I do
believe I've tracked it down to the memory stream
itself. When the DataSet writes to the memory stream,
the XML header isn't written, and the last 2 bytes are
missing. My code for this is:
Dim _ms as New MemoryStream()

ds.WriteXml(_ms,XmlWriteMode.WriteSchema)

Then I pass the _ms to my encryption method. I'm gonna
look into making in in-memory XML file and seeing if I
can transfer that through. One person here at work
suggestion writing the XML to a disk file then encrypting
it, but that would defeat the purpose of encrypting the
file when someone could just copy that file out before
the program has a chance to encrypt it. I would like to
do everything in-memory.

Thanks again.
 

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