Encrypt/Decrypt issue.

Hi All,
I am trying to encrypt text to a textfile(.txt) and then decrypt it in a diff. program.
The encrypting part works fine.
I have tried these functions with a textbox's text and they work perfectly, Now I get errors when trying to decrypt from the .txt file...
System.InvalidCastException was unhandled
       Message="Conversion from string "mscorlib" to type 'Integer' is not valid." &
InnerException: System.FormatException
       Message="Input string was not in a correct format."
Thanks for the help...

Private DES As New TripleDESCryptoServiceProvider
Private MD5 As New MD5CryptoServiceProvider
 
     Private Function Decrypt(ByVal encryptedString As String) As String 
        DES.Mode = CipherMode.ECB
        Dim Buffer As Byte() = Convert.FromBase64String(encryptedString)
        Return ASCIIEncoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(Buffer, 0, Buffer.Length))
    End Function
 
   Dim adCommands As String() = System.IO.File.ReadAllLines(<path>)
            If adCommands.Count > 0 Then
                For Each command As String In adCommands
                    MsgBox(command) 'this show the encryption
                    command = Decrypt(command) 'this throws the error

Open in new window

LVL 9
Hawkvalley1Asked:
Who is Participating?
 
theplonkConnect With a Mentor Commented:
I've rewritten your code. Try this.

The encrypt function can be called like this:
        Encrypt("Test5", "c:\temp\test.txt")
       
The decrypt function can be called like this:
        For Each line As String In Decrypt("c:\temp\test.txt")
            MsgBox(line)
        Next
    Public Sub Encrypt(ByVal stringToEncrypt As String, ByVal fileName As String)
        Dim DES As New TripleDESCryptoServiceProvider
        DES.Mode = CipherMode.ECB
        Dim MD5 As New MD5CryptoServiceProvider()
        DES.Key = MD5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
 
        Dim file As New FileInfo(fileName)
        Dim sWriter As StreamWriter
        If (file.Exists) Then
            sWriter = file.AppendText()
        Else
            sWriter = New StreamWriter(New FileStream(fileName, FileMode.Create))
        End If
        Dim Buffer As Byte() = ASCIIEncoding.ASCII.GetBytes(stringToEncrypt)
        sWriter.WriteLine(Convert.ToBase64String(DES.CreateEncryptor().TransformFinalBlock(Buffer, 0, Buffer.Length)))
        sWriter.Close()
    End Sub
 
    Private Function Decrypt(ByVal fileName As String) As String()
        Dim DES As New TripleDESCryptoServiceProvider
        DES.Mode = CipherMode.ECB
        Dim MD5 As New MD5CryptoServiceProvider()
        DES.Key = MD5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
 
        Dim sReader As New StreamReader(New FileStream(fileName, FileMode.Open))
 
        Dim text As New List(Of String)
        While (Not sReader.EndOfStream)
            Dim Buffer As Byte() = Convert.FromBase64String(sReader.ReadLine())
            text.Add(ASCIIEncoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(Buffer, 0, Buffer.Length)))
        End While
        sReader.Close()
 
        Return text.ToArray()
    End Function

Open in new window

0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Can we see the code that encrypts your original data and writes it to the file?

You've only given us half the picture here...how do you expect us to trouble shoot it?...  =)
0
 
Hawkvalley1Author Commented:
Sure...
Public Shared Function Encrypt(ByVal stringToEncrypt As String) As String 
        DES.Mode = CipherMode.ECB
        Dim Buffer As Byte() = ASCIIEncoding.ASCII.GetBytes(stringToEncrypt)
        Return Convert.ToBase64String(DES.CreateEncryptor().TransformFinalBlock(Buffer, 0, Buffer.Length))
    End Function
 
 If IO.File.Exists(syncFile) Then
                IO.File.AppendAllText(syncFile, Encrypt(<text>) & vbCrLf)
            End If

Open in new window

0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Hawkvalley1Author Commented:
The <text> is just a string variable.
0
 
theplonkCommented:
I replicated your functions and had no problem running the code. It decrypted the lines of the text file.

You've probably already done this, but since your appending to the text file make sure there is no dirty data from earlier attempts. Even remove the file just to make certain.

As an alternate way, you could use a CryptoStream to encrypt and decrypt to a file.

Check out the following references on MSDN:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledescryptoserviceprovider.aspx

0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
It's possible that one of your encrypted strings is interfering with ReadAllLines() and causing it to be split into seperate array entries when being read back in.  If so, using a CryptoStream as theplonk suggests would fix that.
0
 
Hawkvalley1Author Commented:
The lines of encrypted text are stored on one line - which is important.
When I use the messagebox to show me what if found in the file it shows just one line - which is good.
I tried using the cryptoStream minus the key and vector, Encrypt(<string>) this gets me 'the expression does not produce a value.' I don't want a key, do I need the vector? I removed them from the .CreateEncryptor('key,IV')

Public Sub Encrypt(ByVal stringToEncrypt As String) 
        Try
            ' Create or open the specified file.
            Dim fStream As FileStream = File.Open(syncFile, FileMode.OpenOrCreate)
            Dim cStream As New CryptoStream(fStream, _
                                            New TripleDESCryptoServiceProvider().CreateEncryptor(), _
                                            CryptoStreamMode.Write)
            Dim sWriter As New StreamWriter(cStream)
            sWriter.WriteLine(stringToEncrypt)
            sWriter.Close()
            cStream.Close()
            fStream.Close()
        Catch e As CryptographicException
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message)
        Catch e As UnauthorizedAccessException
            Console.WriteLine("A file error occurred: {0}", e.Message)
        End Try
End Sub

Open in new window

0
 
Hawkvalley1Author Commented:
Well it finally showed the 2nd MsgBox (the Decrypted string) to me, the 1st being the encrypted string, and the 2nd one showed up empty after call the function???
0
 
theplonkCommented:
You don't need to set the key and vector. The following test code worked for me.
        Dim tDes As New TripleDESCryptoServiceProvider()
        tDes.Mode = CipherMode.ECB
 
        Dim sWriter As New StreamWriter(New CryptoStream(New FileStream("c:\temp\test.txt", FileMode.Create), tDes.CreateEncryptor(), CryptoStreamMode.Write))
        sWriter.WriteLine("test")
        sWriter.WriteLine("test3")
        sWriter.Close()
 
        Dim sReader As New StreamReader(New CryptoStream(New FileStream("c:\temp\test.txt", FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
 
        While (Not sReader.EndOfStream)
            MsgBox(sReader.ReadLine())
        End While
        sReader.Close()

Open in new window

0
 
theplonkCommented:
Acutally i just thought. You are wanting to encrypt line by line. Where as CryptoStream is encrypting the stream (not line by line). If you try and open the stream to append the file, you will need to decrypt the file stream first, append changes and then encrypt the stream. This is why you might be receiving inner exceptions on file open.
0
 
Hawkvalley1Author Commented:
So where are we, I am confused as ever. I have tried to encrypt the string prior to sending it, same problem.
Does your last comment say that the the code above will not work for me either?
0
 
theplonkCommented:
I think the issue with your original code (that didn't use cryptostream), was because the TripleDes key property had not been set. Each time a new instance of the tripledes is created the key is unique. Try setting the key on decrypt and encrypt and see if that solves your issue with your original code.

        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))

CryptoStream will encrypt and decrypt the file. You will need to decrypt the file first before you append it.

Using your earlier method, you are encrypting the individual lines of text before placing them the text file.

I've placed some test code for the cryptostream below, which decrypts before appending the file and then re-encrypting.

    Private Sub Decrypt(ByVal fileName As String)
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
 
        Dim sReader As New StreamReader(New CryptoStream(New FileStream("c:\temp\test.txt", FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
 
        While (Not sReader.EndOfStream)
            MsgBox(sReader.ReadLine())
        End While
        sReader.Close()
    End Sub
 
    Public Sub Encrypt(ByVal appendText As String, ByVal fileName As String)
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
        
        'Decrypt file content
        Dim fileText As String
        If (New FileInfo(fileName).Exists) Then
            Dim sReader As New StreamReader(New CryptoStream(New FileStream(fileName, FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
            fileText = sReader.ReadToEnd()
            sReader.Close()
        End If
 
        'Append text
        Dim sWriter As New StreamWriter(New CryptoStream(New FileStream("c:\temp\test.txt", FileMode.OpenOrCreate), tDes.CreateEncryptor(), CryptoStreamMode.Write))
        sWriter.Write(fileText + appendText + vbCrLf)
        sWriter.Close()
    End Sub

Open in new window

0
 
Hawkvalley1Author Commented:
Thanks for all the help, sorry for my confusion:
'Private Sub Decrypt(ByVal fileName As String)' I don't see where this value is passed in the sub.
sWriter.Write(fileText + appendText + vbCrLf) If appendText is my string I want to encrypt why are we adding it to what I believe is the decrypted file text - 'fileText'?
'Public Sub Encrypt(ByVal appendText As String, ByVal fileName As String)' fileName is the name of the file I use to add the encrypted text to, but what is the use of "c:\temp\test.txt," and I don't have a temp folder, but I can fix this part if I understand it better.
Thanks again...




0
 
theplonkCommented:
sorry replace "c:\temp\test.txt" with fileName, had forgot to change before uploading.

The process i'm taking is that I decrypt the original file contents to a temporary string ("fileText"), I then append the new string to this text. Then I encrypt this text to a new file (which overwrites the contents of the previous encrypted file).

I've changed the sWriter file stream to be FileMode.Create (before I had it set to FileMode.OpenOrCreate) so it doesn't confuse what is happening.
    Private Sub Decrypt(ByVal fileName As String)
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
 
        Dim sReader As New StreamReader(New CryptoStream(New FileStream(fileName, FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
 
        While (Not sReader.EndOfStream)
            MsgBox(sReader.ReadLine())
        End While
        sReader.Close()
    End Sub
 
    Public Sub Encrypt(ByVal appendText As String, ByVal fileName As String)
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
 
        Dim fileText As String
        If (New FileInfo(fileName).Exists) Then
            Dim sReader As New StreamReader(New CryptoStream(New FileStream(fileName, FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
            fileText = sReader.ReadToEnd()
            sReader.Close()
        End If
 
        Dim sWriter As New StreamWriter(New CryptoStream(New FileStream(fileName, FileMode.Create), tDes.CreateEncryptor(), CryptoStreamMode.Write))
        sWriter.Write(fileText + appendText + vbCrLf)
        sWriter.Close()
    End Sub

Open in new window

0
 
Hawkvalley1Author Commented:
Ok I got it working...
When I use the MsgBox(sReader.Readline) it shows as the original text prior to being encrypted. So I changed it back to a function to return this to the string. Some modifing of your code. I need to check for multiple lines.
Public Sub Encrypt(ByVal appendText As String, ByVal fileName As String)  
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
        Dim fileText As String = Nothing
        'Append text
        Dim sWriter As New StreamWriter(New CryptoStream(New FileStream(fileName, FileMode.OpenOrCreate), tDes.CreateEncryptor(), CryptoStreamMode.Write))
        sWriter.Write(appendText + vbCrLf)
        sWriter.Close()
        sWriter = Nothing
End Sub
 
 Public Function Decrypt() As String  
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
        Dim sReader As New StreamReader(New CryptoStream(New FileStream(<path>, FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
        While (Not sReader.EndOfStream)
           Return sReader.ReadLine
        End While
        sReader.Close()
    End Function
 
'so
 
command = Decrypt() 'to recall it

Open in new window

0
 
Hawkvalley1Author Commented:
Nevermind, it worked for 1 time now not so much??? Very frustrating...Or at least the Decryptor is working, I don't know, it's been a long day of coding, and my brain is hurting, somebody call 911, cause I can't find the 11 button...
0
 
theplonkCommented:
You can use a string array as a return type. Just use a List(Of String) to create the string array of lines.

And call it like this:
For Each line As String In Decrypt("c:\temp\test.txt")
            MsgBox(line)
Next

    Private Function Decrypt(ByVal fileName As String) As String()
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
 
        Dim sReader As New StreamReader(New CryptoStream(New FileStream(fileName, FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
 
        Dim text As New List(Of String)
        While (Not sReader.EndOfStream)
            text.Add(sReader.ReadLine())
        End While
        sReader.Close()
 
        Return text.ToArray()
    End Function

Open in new window

0
 
Hawkvalley1Author Commented:
You are awesome for sticking with this, I have stopped banging my head, things are blurry, but that makes sense.

The Encrypt Sub is not sending the encrypted strings to the file, just reg. text and not on a new line - this is a problem. Well the first line is encrypted then the others are reg. text.???

Then how to call the text.ToArray in the event that calls the Decrypt() so I can do something with each line seperately? Where I use to call: Dim adCommands As String() = System.IO.File.ReadAllLines(<path>) code was in ~17 posts ago...
0
 
Hawkvalley1Author Commented:
Sorry I got the array part, I'm just getting tired.
0
 
theplonkCommented:
That's no prob.

Delete your existing encrypted file to make sure there is no old data.

Try the encrypt sub I posted above. Under my tests it encrypts the file properly.

In your code (17 posts ago) you were calling decrypt by:
  Dim adCommands As String() = System.IO.File.ReadAllLines(<path>)
            If adCommands.Count > 0 Then
                For Each command As String In adCommands
                    command = Decrypt(command)

You would only need to use:
For Each command As String In Decrypt(<path>)
            MsgBox(command) 'Or replace with whatever you want to do.
Next
    Public Sub Encrypt(ByVal appendText As String, ByVal fileName As String)
        Dim tDes As New TripleDESCryptoServiceProvider
        tDes.Mode = CipherMode.ECB
        Dim md5 As New MD5CryptoServiceProvider()
        tDes.Key = md5.ComputeHash(Encoding.ASCII.GetBytes("TestKey"))
 
        Dim fileText As String
        If (New FileInfo(fileName).Exists) Then
            Dim sReader As New StreamReader(New CryptoStream(New FileStream(fileName, FileMode.Open), tDes.CreateDecryptor(), CryptoStreamMode.Read))
            fileText = sReader.ReadToEnd()
            sReader.Close()
        End If
 
        Dim sWriter As New StreamWriter(New CryptoStream(New FileStream(fileName, FileMode.Create), tDes.CreateEncryptor(), CryptoStreamMode.Write))
        sWriter.Write(fileText + appendText + vbCrLf)
        sWriter.Close()
    End Sub

Open in new window

0
 
Hawkvalley1Author Commented:
Ok, I started from scratch - no file -, it created one and sent the string encrypted, then when I add the second string, it addes it to the same line and now the encryption looks chinese(not like the first string originally looked).
I used your exact code. Does it matter if there are special characters in the string - like '(,')' ?
0
 
theplonkCommented:
From my test, the encryption displays one long line of many different special characters :)

Because you're now encrypting the whole file rather then on a per line basis. The contents of the file, should be a single line of encryption that grows each time it is re-encrypted.

Did you have any success decrypting your info?
0
 
Hawkvalley1Author Commented:
I made a loop in the first program to encrypt then decrypt and send it back to the file, it encrypted - found each line - decrypted each line then resent it back again as encrypted strings, so your code does work - heck the first code I had should have worked, the problem is with my second progam that is trying to do the same thing won't. The decrypt files are identical in both so it makes no sense why this will not work. At my witts end with this...
0
 
Hawkvalley1Author Commented:
This is my loop. And i can get the encryption lines on seperate lines, each one needs to be read as its own line later. Both programs run the same decryption Fucntion, and are both called the same way. So to show this loop works - the lines would add like 1 then 3 then 7 lines as it addes the ones found back with one new one - because it does not delete any lines. I have checked the filePath - no problem there. No cure in sight...
 Public Function Encrypt(ByVal stringToEncrypt As String) As String 
        DES.Mode = CipherMode.ECB
        Dim Buffer As Byte() = ASCIIEncoding.ASCII.GetBytes(stringToEncrypt)
        Return Convert.ToBase64String(DES.CreateEncryptor().TransformFinalBlock(Buffer, 0, Buffer.Length))
End Function
    Public Function GetEncryptedFile(ByVal fileName As String) As String()
        DES.Mode = CipherMode.ECB
        Dim fileList As New List(Of String)
        If (New FileInfo(fileName).Exists) Then
            Dim sReader As New StreamReader(New FileStream(fileName, FileMode.Open))
            While (Not sReader.EndOfStream)
                Dim Buffer As Byte() = Convert.FromBase64String(sReader.ReadLine)
                fileList.Add(ASCIIEncoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(Buffer, 0, Buffer.Length)))
                MsgBox(ASCIIEncoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(Buffer, 0, Buffer.Length)))
            End While
            sReader.Close()
        End If
        Return fileList.ToArray
    End Function
 
 Dim newList As Array = GetEncryptedFile(syncFile)
            For Each line In newList
                line = Encrypt(line)
                IO.File.AppendAllText(syncFile, line + vbCrLf)
            Next
            nextLine = Encrypt(nextLine)
            IO.File.AppendAllText(syncFile, nextLine + vbCrLf)

Open in new window

0
 
Hawkvalley1Author Commented:
Maybe I am missing the point and it is doing it's job not letting me access the encrypted file with diff. program???
0
 
theplonkCommented:
I've tested my code in two different assemblies and it works.

The DES.Key (hash key) is the key.
0
 
Hawkvalley1Author Commented:
Excellent, and even more excellent than excellent.....You deserve like 5000 points for this. Thanks for sticking with me.
0
 
theplonkCommented:
That's no problem. Anytime. Glad it finally worked :)
Was determined to get this one.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.