[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Encrypt/Decrypt issue.

Posted on 2009-02-21
28
Medium Priority
?
394 Views
Last Modified: 2012-05-06
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

0
Comment
Question by:Hawkvalley1
  • 15
  • 11
  • 2
28 Comments
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 23703281
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23703294
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23703354
The <text> is just a string variable.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 8

Expert Comment

by:theplonk
ID: 23703476
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
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 23703563
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23705074
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23706189
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
 
LVL 8

Expert Comment

by:theplonk
ID: 23706292
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
 
LVL 8

Expert Comment

by:theplonk
ID: 23706316
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23707260
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
 
LVL 8

Expert Comment

by:theplonk
ID: 23707579
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23707951
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
 
LVL 8

Expert Comment

by:theplonk
ID: 23708103
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23708138
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23708248
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
 
LVL 8

Expert Comment

by:theplonk
ID: 23708252
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23708464
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23708498
Sorry I got the array part, I'm just getting tired.
0
 
LVL 8

Expert Comment

by:theplonk
ID: 23708500
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23711215
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
 
LVL 8

Expert Comment

by:theplonk
ID: 23714887
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23715947
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23716189
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
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 23716644
Maybe I am missing the point and it is doing it's job not letting me access the encrypted file with diff. program???
0
 
LVL 8

Accepted Solution

by:
theplonk earned 2000 total points
ID: 23716738
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
 
LVL 8

Expert Comment

by:theplonk
ID: 23716761
I've tested my code in two different assemblies and it works.

The DES.Key (hash key) is the key.
0
 
LVL 9

Author Closing Comment

by:Hawkvalley1
ID: 31549689
Excellent, and even more excellent than excellent.....You deserve like 5000 points for this. Thanks for sticking with me.
0
 
LVL 8

Expert Comment

by:theplonk
ID: 23717077
That's no problem. Anytime. Glad it finally worked :)
Was determined to get this one.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month19 days, 4 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question