ram_son Posted August 12, 2007 Posted August 12, 2007 I have been trying my hand at encrypting and decrypting files using vb.net and kind of succeded in encrypting and decrypting one file at a time. But I am having hard time decrypting 4 files that I need done before the form loads in an app. I am using a snippet that uses base64 that worked when I used vb6; but I am new to vb.net and have not been able to do it. In the program I am only interested in decoding the files. So let's say I have four files that I encoded using base64 with the password "abc" and now have four files a.enc, b.enc, c.enc,and d.enc that are in the prg dir. I would like to decode them back to text files to a temp directory (C:\temp) and use them till the program is stopped.What parts of the code do I need in the program and do I get all four files decoded. It's not like I haven't tried but the best I did was end up with four files with different names but same content. Any assistance will be appreciated. Quote
Administrators PlausiblyDamp Posted August 12, 2007 Administrators Posted August 12, 2007 Without seeing the code you have so far it is hard to say exactly what changes you should be making ;) Just out of interest are the files encrypted and then converted to Base64 as Base64 itself isn't a form of encryption - it is just a means of encoding binary files in an ASCII form. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
ram_son Posted August 13, 2007 Author Posted August 13, 2007 This is what I am using right now.Like I said I am not sure if what I am doing is remotely the correct way to do this. The files are already encoded using a utility that uses the same code snippet. So I have the DecodeToByte and DecodeFile functions in the form like this: Function DecodeToByte(ByVal enc As String) As Byte() Dim bt() As Byte bt = System.Convert.FromBase64String(enc) Return bt End Function Sub DecodeFile(ByVal srcFile As String, ByVal destFile As String) Dim src As String Dim sr As New IO.StreamReader(srcFile) src = sr.ReadToEnd sr.Close() Dim bt64 As Byte() = DecodeToByte(src) If IO.File.Exists(destFile) Then IO.File.Delete(destFile) End If Dim sw As New IO.FileStream(destFile, IO.FileMode.CreateNew) sw.Write(bt64, 0, bt64.Length) sw.Close() End Sub Then I want to decode the files to text files and have them displayed as the text in 4 labels; so I am trying this: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim destfile1 As String = "c:\temp\a1.txt" Dim srcfile1 As String = "F:\a1.enc" Dim src1 As String = "a1.enc" Dim sr1 As New IO.StreamReader(srcfile3) src1 = sr1.ReadToEnd sr1.Close() DecodeToByte(src1) 64 = DecodeToByte(src1) Dim bt64 As Byte() = DecodeToByte(src1) If IO.File.Exists(destfile1) Then IO.File.Delete(destfile1) End If Dim sw1 As New IO.FileStream(destfile1, IO.FileMode.CreateNew) sw1.Write(bt64, 0, bt64.Length) sw1.Close() FileClose() I repeat this four times for the four different files by changing everywhere there is the figure 1 to 2 ,then 3 and 4, so that it is pointing to the second file "a2.enc", "a2.txt" and "srcFile2" and "destFile2" and so on.What I get is 4 files in C:\temp (a1.txt thru a4.txt) but their contents are the same as the first. So how do they all end up with the same content? I hope this makes it easier to understand what I am trying to do. Needless to say any help would be greatly appreciated. Quote
Administrators PlausiblyDamp Posted August 13, 2007 Administrators Posted August 13, 2007 Could you attach the actual project and if possible the sample files you are using? Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
ram_son Posted August 13, 2007 Author Posted August 13, 2007 I was working on the encryption outside of the project and have messed it up since then.. I'll definitely see if I can get it back where it was and then post and attach the files. In the meantime do you see anything wrong with the code above that would make the contents of the files be the same even though they are totally different originally. Is this code actually giving the instructions to write "a1.txt" and when done stop and start writing a new file named "a2.txt"; or is it writing and then overwriting with the contents of the first file? It might take a little while to get these files ready but I'll definitely post again ... Thanks Quote
ram_son Posted August 13, 2007 Author Posted August 13, 2007 (edited) I tried to duplicate what happens in these files I am uploading.However, now I cannot even get the text to be displayed in the labels, but you can see how the four *.enc files are all decoded with the same content inside the application directory. I encoded them with a utility that doesn't even ask for a password which I have to also fix. Please take a look at this and let me know how much of a mess it is.ENCRYPT.zip Edited August 13, 2007 by PlausiblyDamp Quote
MrPaul Posted August 15, 2007 Posted August 15, 2007 Base64 is not encryption Why don't you use your DecodeFile method? It clearly works: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load DecodeFile("a1.enc", "a1.txt") DecodeFile("a2.enc", "a2.txt") DecodeFile("a3.enc", "a3.txt") DecodeFile("a4.enc", "a4.txt") 'Load labels here End Sub As for the label loading part, you could put that into its own method as well, to avoid all the repeated code. I encoded them with a utility that doesn't even ask for a password which I have to also fix. As PlausiblyDamp mentioned above, Base64 is an encoding scheme, not an encryption scheme, so cannot be made to use a password. If you want the files to be encrypted you should use classes in the System.Security.Cryptography namespace. Also, decrypting files and storing their contents in an unencrypted file is a gaping security hole and makes the whole encryption process pointless. Once the contents of the files has been decrypted I suggest it is stored in program variables. Finally, if you do password-protect your encrypted files, I suggest you do not place the password plainly in the code as this is easy to discover just by opening the program in a text editor or a disassembler. Good luck :) Quote Never trouble another for what you can do for yourself.
ram_son Posted August 16, 2007 Author Posted August 16, 2007 Re: Base64 is not encryption Thanks MrPaul.. I knew it would have to be something that simple. I actually got the same results by creating a module with the decode procedure and then calling it during form load similar to what you have suggested. I still don't know what was making the four files get decoded with the same content though. Obvously, I am just a beginner when it comes to programming, especially wth vb.net, and have to ask you how could I do that when it comes to using classes. I would actually much rather have he files encrypted with a password but when the program runs it needs to access the files as text in order to display the content in the labels. Is there a way of doing that without decrypting or decoding the files. Could the files be stored in memory as text and accessed there instead of in temporary files or would that slow down the process considerably. Thanks again for your help. Quote
MrPaul Posted August 16, 2007 Posted August 16, 2007 Not writing to file I still don't know what was making the four files get decoded with the same content though.[/Quote] Sorry for not explaining that. The problem was that you were not assigning the decoded data to the variable before you wrote it to the file: 'For file 1 Dim bt64 As Byte() = DecodeToByte(src1) '... sw1.Write(bt64, 0, bt64.Length) 'For file 2 DecodeToByte(src2) '... sw2.Write(bt64, 0, bt64.Length) Notice the difference? With the first file the decoded data is assigned to variable bt64 which is then written to the file, but with the second file it is not assigned, so the bt64 variable still contains the data from the first file, which is then written again - same with the third and fourth files. The solution is therefore to assign the return value of DecodeToByte to the variable bt64: bt64 = DecodeToByte(src2) '... bt64 = DecodeToByte(src3) '... bt64 = DecodeToByte(src4) Could the files be stored in memory as text and accessed there instead of in temporary files or would that slow down the process considerably. Yes they could, and with files this size there is barely any overhead at all - it certainly wouldn't slow anything down. After using DecodeToByte to obtain the file contents, you would then convert the byte data to a string which can be manipulated as needed: 'Decode file from base64 Dim bt64 As Byte() = DecodeToByte(src1) 'Convert byte data into a string Dim fileData As String = Encoding.Default.GetString(bt64) 'Split string into individual lines Dim fileLines As String() = fileData.Split(ControlChars.CrLf) 'Set label text to appropriate line Label1.Text = fileLines(index1) Good luck :cool: Quote Never trouble another for what you can do for yourself.
ram_son Posted August 16, 2007 Author Posted August 16, 2007 Re: Not writing to file Now I understand where the problem was...Thanks for explaining that . As far as storing the files into memory I'm going to try that and see how it works since the actual files are quite a bit larger than the sample files-- they run around 1400 lines each.. I'll see if I can get it working and will post the results. Please keep checking as I might need some more help. I really appreciate your help and patience. Quote
ram_son Posted August 16, 2007 Author Posted August 16, 2007 Re: Not writing to file I tried the code for storing the files into memory and had partial success.I worked first with the sample files and after some trouble succeeded in getting the lablels to display the number "10" in each which is the index number in each file.Then I replaced the sample files with the actual files to be used and got the index numer of "1400" in the labels. Judging by the speed of the files being decoded and loaded it doesn't seem like it would cause any trouble. So I think the idea is excellent. But where I ran into trouble is the procedure of skipping the first line of index numbers and then using a button to move from one line to the next.Originally I was using a routine to load the labels that relied on "line_number1" and "line_value1()"; so I substituted "line_value1()" for "filelines" but when I click the next button I get an error "object reference not set for an instance of an object" at Label1.text = line_value1(index1) The question is then is this the right thing to do using line_value1 to replace filelines and is this problem related to the fact that the index number are displayed in the labels instead of the first line of the content.Any suggestions? Quote
MrPaul Posted August 16, 2007 Posted August 16, 2007 Zero based indexing If you want to use the line_value1 variable instead of fileLines that's fine, but you must change it where I have used fileLines in my code, so that it reads: line_value1 = fileData.Split(ControlChars.CrLf) Label1.Text = line_value1(index1) The reason the number 1400 is appearing is that the text "1400" is the first line in the file and so will be the first item in the line_value1 array - if you set index1 to 1 then you'll get the next line, 2 for the third line etc. Remember arrays in VB.Net are zero based, so the first item ("1400") is at index 0. :) Quote Never trouble another for what you can do for yourself.
ram_son Posted August 16, 2007 Author Posted August 16, 2007 Re: Zero based indexing I did that and I get an error that "the path is too long after being fully qualified.Make sure path is less than 260 characters." where I open the file: Dim i As Integer Dim line_input(1) As String Dim FILE_NAME1 As String = fileData1 'Dim line_value1 As String FileOpen(1, FILE_NAME1, OpenMode.Input) <<error points here Input(1, line_number1) For i = 1 To 1326 Input(1, line_value1(i)) Next i The intellisense shows the contents of the decoded file at the spot of the error!! Do I have control over the path? Quote
MrPaul Posted August 16, 2007 Posted August 16, 2007 No need for file handling The code I posted previously was meant to replace the file handling, since the variable fileLines (or line_value1 if you prefer) already contains the entire file, separated into lines. You can then access an individual line of the file using its index: 'Decode file from base64 Dim bt64 As Byte() = DecodeToByte(src1) Dim fileData As String = Encoding.Default.GetString(bt64) Dim line_value1 As String() = fileData.Split(ControlChars.CrLf) 'At this point in the code, line_value1 is an array containing the entire 'decoded contents of the first file, each element of the array corresponding 'to one line in the file. We can therefore access any line in the file by 'using an index value, starting from 0 (the first line). There is no need for 'ANY further file handling after this point! 'First item of line_value1 contains the number line_number1 = Integer.Parse(line_value1(0)) 'Set label text to appropriate line Label1.Text = line_value1(index1) Quote Never trouble another for what you can do for yourself.
ram_son Posted August 17, 2007 Author Posted August 17, 2007 Re: No need for file handling I still need a routine for the "next" button, right? This is what I had beforeDim i As Integer Dim clickcount As Integer If index1 < 1323 Then index1 = index1 + 1 Else MsgBox("This is the last record of the data") End If Label1.Text = line_value1(index1) Label2.Text = line_value2(index1) Label3.Text = line_value3(index1) Label4.Text = line_value4(index1) When I click the next button now I get an unhandled exception error(object not set to an instance of an object. Quote
MrPaul Posted August 17, 2007 Posted August 17, 2007 Populate other variables You need to instantiate and populate the variables line_value2, line_value3 and line_value4 in the same way that you did for line_value1. bt64 = DecodeToByte(src2) fileData = Encoding.Default.GetString(bt64) line_value2 = fileData.Split(ControlChars.CrLf) bt64 = DecodeToByte(src3) fileData = Encoding.Default.GetString(bt64) line_value3 = fileData.Split(ControlChars.CrLf) bt64 = DecodeToByte(src4) fileData = Encoding.Default.GetString(bt64) line_value4 = fileData.Split(ControlChars.CrLf) For future reference, when an exception occurs, Visual Studio will break into the debugger so you can see exactly what line the exception occured on, and then by hovering the mouse over variables you can tell which one has not been instantiated (is set to Nothing). Quote Never trouble another for what you can do for yourself.
ram_son Posted August 17, 2007 Author Posted August 17, 2007 Re: Populate other variables I already have done that (I'm learning!!) and got the labels populated but the next button doesn't seem to work. I got it working by having the decoding done in the buttons for next and previous procedures followed by the next and previous click functions. In other words the text doesn't appear in the labels until I hit the next button and keeps moving to the next line with every click.Then I use the previous button to go backwards.It seems to work ok, so if there is no harm I guess it should be alright. If I use the form load event it loads the labels but doesn't move on to the next record. Quote
ram_son Posted August 17, 2007 Author Posted August 17, 2007 Re: Populate other variables Mr Paul... I really want to thank you for all the help and guidance and patience that you demonstrated. I learned quite a bit and hope to learn a lot more practical programming stuff from people like yourself -- in addition to the tutorials of course. I have to say that it is knowledgeable and helpful members like you who make these forums worth visiting. BTW you did mention something about not placing the password plainly in the code, but you didn't suggest alternatives. Do you have any advice on this topic? Quote
MrPaul Posted August 19, 2007 Posted August 19, 2007 Encryption BTW you did mention something about not placing the password plainly in the code, but you didn't suggest alternatives. Do you have any advice on this topic? I suppose it depends why you need the encryption in the first place. For example, you might request that the user enters the password - if the application is going to display the contents of the files then encrypting them is fairly pointless if anyone can just open the application, right? As for placing a password in code, there are practically infinite ways you could go about it, depending on how much you want to hide it. For example, a very poor system might be to store the password backwards, then reverse it before decrypting the files: Const storedPassword As String = "drowssap" realPassword = storedPassword.Reverse() Other techniques might involve jumbling the characters in the password, and then unjumbling them before decrypting: Const storedPassword As String = "sopwrsad" realPassword = storedPassword(2) & storedPassword(6) & _ storedPassword(0) & storedPassword(5) & _ storedPassword(3) & storedPassword(1) & _ storedPassword(4) & storedPassword(7) Maybe using two constants to store the password then combining them: Const firstPassword As String = "pswr" Const secondPassword As String = "asod" realPassword = String.Empty For i As Integer = 0 To firstPassword.Length - 1 realPassword &= firstPassword(i) & secondPassword(i) Next Slightly more advanced approaches might also involve enciphering the password: Const filePassword As String = "qbttxpse" realPassword = String.Empty For i As Integer = 0 To filePassword.Length - 1 realPassword &= Chr(Asc(filePassword(i)) - 1) Next And of course you could combine these techniques. Bear in mind that no matter what you do, the password can be discovered by anyone using an MSIL disassembler and then stepping through your code. Good luck :) Quote Never trouble another for what you can do for yourself.
ram_son Posted August 22, 2007 Author Posted August 22, 2007 Re: Encryption The idea of the password is just to make it a little harder to get at the contents of the files. The solution of storing the files in memory is excellent because the files don't exist as text even temporarily. So the way I have things right now, the text files exist in the encoded state; you raised the point that encryption with a password might be safer. So I am looking for an encryption/ decryption routine instead of the encoding/ decoding one as this makes it a little harder to decrypt the files. Another question would an obfuscator prevent an MSIL disassembler from taking the code apart? Quote
Administrators PlausiblyDamp Posted August 22, 2007 Administrators Posted August 22, 2007 Re: Encryption Out of interest what are the files being used for? If there is no real reason to store the contents on disk then simply keeping them in memory is going to be the easiest solution. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
ram_son Posted August 23, 2007 Author Posted August 23, 2007 Re: Encryption The contents of the four files are to be displayed in corresponding sequence as the text of four labels. Can you get them in memory without storing them on the disk? Quote
Administrators PlausiblyDamp Posted August 31, 2007 Administrators Posted August 31, 2007 Re: Encryption Where is the information contained in the files coming from? If you are reading it from some other source (i.e. Database or website) then you could just read the values into a string directly and assign that to the relevant label. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.