Re: how can i encrypt a file?
Quote:
Originally Posted by
katy_price
do you mean i have to put my filenames in here
Code:
// Open files:
FileStream ^fInput;
try {
fInput = gcnew FileStream("john.txt", FileMode::Open, FileAccess::Read);
}
catch (...) {
return false;
}
FileStream ^fOutput = gcnew FileStream("can.txt", FileMode::Create, FileAccess::Write);
No. It's easiest to consider the Crypt() function a black-box and leave it unchanged. Instead, you should pass the file names as parameters when you call it:
Code:
if (!Crypt("john.txt", "can.txt", "WhateverPassword", bCryptMode)) {
// Run away and cry...
return 1;
}
Of course you wouldn't hard-code neither the file names nor the password in your actual code but I hope you get the idea.
Quote:
like i've put john.txt, am i required to have the full path?
That depends on whether the file is located in the current working directory (CWD) of your app or not. If you're not sure it's alway better to use the fully qualified path; that would never do any harm if it's actually not needed.
Quote:
anyway this is still weird for me how do i serparate the dercyption code from the encryption as they are supposed to be in separate programs.
In the scenario we have here it's not really sensible to separate the encryption and decryption code. The two are so similar that they're best left together in a common function. Whether you actually want to encrypt or decrypt is determined by the bMode parameter you pass to Crypt().
Re: how can i encrypt a file?
Quote:
Originally Posted by
Eri523
No. It's easiest to consider the Crypt() function a black-box and leave it unchanged. Instead, you should pass the file names as parameters when you call it:
Code:
if (!Crypt("john.txt", "can.txt", "WhateverPassword", bCryptMode)) {
// Run away and cry...
return 1;
}
Of course you wouldn't hard-code neither the file names nor the password in your actual code but I hope you get the idea.
why cant i do that how else would i get the file to open. where do i put it then. plus where do i put your code in my program for it to work? how will it know what file to encypt and decrypt if i dont put the file name in.
i am so confused i dont understand what your saying. plus would the file that is encrypted always be encrypted? even after i decrypt it? like after the user opens, sees the file edits it etc...and then closes it, does the encryted file remain encrypted even when edited?
do i put this in my main.cpp file? do i call the crypt function when the user enrolls/login? i dont totally understand. :(
Re: how can i encrypt a file?
Quote:
Originally Posted by
katy_price
why cant i do that how else would i get the file to open. where do i put it then. [...] how will it know what file to encypt and decrypt if i dont put the file name in.
If you refer to opening the file for encryption/decryption, this is encapsulated inside the Crypt() function and this one just needs the file name to access the file. And, as I understand your design, you would leave opening the file for viewing/editing up to the associated application, e.g. Notepad for .txt.
And of course you indeed need to pass the file names to Crypt(), but you would most likely do that as a string variable, not a hard-coded string literal.
Quote:
plus where do i put your code in my program for it to work?
The best place to put it is the compilation unit (i.e. .cpp file) from where you call it, and most likely it would only be called from a single class or at least compilation unit. That way you don't need to prototype Crypt(). main.cpp would actually be about the worst possible place to put it, BTW.
Quote:
plus would the file that is encrypted always be encrypted? even after i decrypt it? like after the user opens, sees the file edits it etc...and then closes it, does the encryted file remain encrypted even when edited?
While the user views/edits the file you would have two copies of the file, one encrypted and one decrypted. It actually would not be a good idea to try to encrypt/decrypt the file in-place, i.e. passing the same file name as input file and output file to Crypt() because then the function would try to simultaneously read and write the same file which is pretty likely to fail. After the user has edited the file you would need to re-encrypt it because then the encrypted and decrypted copy of the file are out of sync.
There actually is a way of leaving the file encryped even while you edit it and handle encryption/decryption transparently: EFS. But I don't think this is applicable in your program.
Quote:
do i call the crypt function when the user enrolls/login?
Decrypting the file upon login of the user and re-encrypting it (possibly only in case the user actually changed it) upon logout is a natural option. Of course that would mean there is a decrypted copy of the file the entire time the user stays logged in, which I think isn't critical here. An option to only have a decrypted copy the minimum required time span would be to decrypt it just prior to opening it for viewing/editing and re-encrypting it right after that's finished, but depending on the way you open the file that may be complicated. From a security point of view this is safer, but IMO not really necessary in your app.
Quote:
i dont totally understand. :(
Just hold on! :thumb: I think we're really close now and will finaly get that sorted out, just like in all those other threads... :)
Re: how can i encrypt a file?
Quote:
Originally Posted by
katy_price
do you mean pass a string like this?
Code:
system("C:\\Users\\katanya\\Desktop\\monk.drn.txt");
or is the above how i would open the file after i decrypt it like so (below)?
Code:
if (!Crypt("john.txt", "can.txt", "WhateverPassword", bCryptMode)) {
// Run away and cry...
return 1;
}
The first snippet would be for opening the file, the second one for either encryption or decryption, depending on the value of bCryptMode. It wouldn't make sense to hard-code the file names (and the password) like it is done in both samples when you do this in your actual app though, unless you have a single common file shared by all users.
Quote:
so il put the code you gave me in a cpp file not a header file aswell? will i need a pointer to call the function?
Quote:
The best place to put it is the compilation unit (i.e. .cpp file) from where you call it,
Oh do you mean like my login.cpp file, il put it in there, that way i dont need a pointer. i am abit confused on how to call the actual function if i wanted to decrypt it? i would call the encrypt function in the enrollment.cpp file. that would mean i'd have the your code twice in the program?
If you only need to call Crypt() from a single one of your .cpp files, the easiest option would be to paste the Crypt() function definition into that file. In that case you wouldn't need a .h file for it. And no, you don't need a pointer to call it.
If you need to call it from more than one .cpp file, having the Crypt() function definition in each of them isn't really an option. In fact it would lead to linker errors unless you take special precautions. In this case it's best to put the Crypt() definition into its own .cpp file (e.g. Crypt.cpp) and add that file to your project. Then you would need a .h file for it and it has to be #included in every .cpp file the function is called from. The .h file wouldn't really be spectacular. This is enough:
Code:
// Crypt.h
#pragma once
bool Crypt(String ^, String ^, String ^, bool);
Quote:
the thing is, once the file opens i was planning on making my program close, is that not a good idea because if the user edits and closes the file it would not get re-encrypted because my program would have closed before the user closes the file. if i was to change it how would my program know when to re-encrypt it, i would need to connect the closing of the file with the re-encyption of the file. how?
Your app should stay open at least until re-encryption of the file. How else should it know which user is logged in if any at all when it comes to re-encryption?
The more secure variant of leaving the file unencrypted for the minimum time requires your app to detect when the app launched for viewing/editing the file is closed. In a native app, one option would be to use ShellExecuteEx() instead of system() to open the file and then wait for the process handle returned by that function to get signaled which indicates that the process has finished. But this approach can quickly get pretty complex (you will likely need a worker thread for that, e.g.), so I would recommend using the simpler variant of decrypting the file upon login of the user and re-encrypt it upon logout. Aside from that, ShellExecuteEx() is a native API function (BTW, system() is a native function as well, though it's no Windows API but part of the C++ runtime library) and while you can call them from C++/CLI it is usually preferable to use a .NET equivalent if there is one. I'm sure there actually is one for this, I just didn't find it yet.
In contrast, determining whether re-encryption is needed is much simpler. I would suggest to clear the archive attribute of the decrypted file right after decryption. When time comes for possible re-encryption, you simply check whether that attribute is set now. If it is, the file has been changed in the meantime and you need to re-encrypt it. This would involve the .NET runtime functions IO::File::GetAttributes() and SetAttributes().
Quote:
plus how comes this is in the main.cpp....where would i put this part of the code then. i have a main function already.
In a console app it is common practice to have a function like Crypt() in the compilation unit containing main() (which usually is not called main.cpp, BTW). In a Windows Forms app, however, there usually is no reason to change anything in main.cpp at all. Here you would put it into login.cpp, enrollment.cpp or its own compilation unit like Crypt.cpp, e.g, but not into more than one of them at a time. I have already pointed this out above.
EDIT: The way I described defining Crypt() in its own compilation unit above would put it into the global namespace. While this works, it isn't necessarily considered good style. It should better reside in the namespace that contains all your Windows Forms classes, but I'll leave that for later at the moment for the sake of simplicity (and weariness after writing this long post).
Re: how can i encrypt a file?
Quote:
Originally Posted by
Eri523
depending on the value of bCryptMode
how do i determining the value of bmode? this is weird, how would i call the crypt() function if i wanted to encrypt a file? if i cant put the name of the password as the parameter?
i dont know how i'm supposed to call the function if i wanted to encrypt a file. i thought below was right, but apparently i shouldn't put the name of the password or filename when calling the file, so how would this work where would i put them?
Code:
Crypt("peter.txt", "john.txt", good123, .... )
however i still dont know how i would write the bmode lets say for encryption?
Quote:
so I would recommend using the simpler variant of decrypting the file upon login of the user and re-encrypt it upon logout.
i dont have a logout option, this isnt necessary, all i want is for when the user closes the file that my program closes too, whilst the user edits the file i will have the login window be invisible and the program end when they close the file...however i will deal with this section after i actually get the file to be encrypted and decrypted, at this rate i dont think it will happen.
Re: how can i encrypt a file?
Quote:
Originally Posted by
katy_price
how do i determining the value of bmode? this is weird, how would i call the crypt() function if i wanted to encrypt a file? if i cant put the name of the password as the parameter?
It's that simple: Set the boolean mode parameter to true if you want to encrypt and to false if you want to decrypt.
Of course you need to specify the password for both encryption and decryption. And of course they have to be the same (for the same file) or you won't get a valid output file after decryption. Imagine you were a hacker who wants to steal Katy's secret file, and you have the Crypt() function. If you could use it to decrypt the file without specifying the password you would instantly get hands on the secret data and hence the encryption would be pointless. ;)
Quote:
i dont know how i'm supposed to call the function if i wanted to encrypt a file. i thought below was right, but apparently i shouldn't put the name of the password or filename when calling the file, so how would this work where would i put them?
Code:
Crypt("peter.txt", "john.txt", good123, .... )
It would be right, provided that a) the file names you use for encryption and decryption are always the same, b) good123 has been declared as
and previously set to the appropriate password and c) the .... is replaced by a boolean variable (or a boolean expression) that evaluates to true because you want to encrypt.
Quote:
i dont have a logout option, this isnt necessary, all i want is for when the user closes the file that my program closes too, whilst the user edits the file i will have the login window be invisible and the program end when they close the file
Well, then you have to bite the bullet and use the "wait for process to finish" approach I described above. I think I'll go and look for a .NET alternative to ShellExecuteEx() in advance, and maybe we're lucky and this .NET feature simplifies things a bit... :) Or maybe someone who knows comes along, reads the thread despite the 30+ posts it already has and tells us what to use.
Quote:
...however i will deal with this section after i actually get the file to be encrypted and decrypted, at this rate i dont think it will happen.
Dividing programming tasks into manageable steps is always a good idea, especially if the task is of the somewhat more complex kind, and that process waiting thing definitely doesn't simplify the app as a whole.
For testing purposes you can replace the process waiting thing by a simple box containing a button that says "click me when you're done editing the file". Actually, you don't even need to create a form for this. A simple message box will do. That way you can test the parts of the app you already have without having that complex waiting stuff.
Re: how can i encrypt a file?
i can't convert my program from vc++ express 2008 to 2010 i get the following error: The following error has occurred during XML parsing: File: System error: -2147154677. The file has failed to load.
i dont know what it means or how to fix it. i need to convert to 2010 in order to use the AesManaged class and the copyTo function.
Re: how can i encrypt a file?
Sorry, I have no experience with that kind of error and don't know how to fix it. :( But maybe one of the experts comes along who knows about that and posts a solution. However, there's a chance that the particular expert who knows the answer doesn't read this thread anymore because it's become too long. While it's likely that some of them aren't around durig the holidays anyway, I would suggest you start a separate thread about that issue if you haven't got a solution (or at least a hint to one) yet some days after the holidays.
But did you happen to try to compile your project (with the Crypt() function) under 2008 after you have installed 2010? Maybe that works now that .NET 4 is available.
Re: how can i encrypt a file?
Quote:
Originally Posted by
Eri523
But did you happen to try to compile your project (with the Crypt() function) under 2008 after you have installed 2010? Maybe that works now that .NET 4 is available.
The crypt function doesnt work on visual c++ 08 the lastest .net is 3.5 so i couldnt compile it
Re: how can i encrypt a file?
sorry i mean the 'AesManaged' class is not in .net 3.5 is there an equivalent to AesManaged in 3.5. CopyTo isn't either. i can't use 2010 because my program will not convert.
Re: how can i encrypt a file?
i found the RijndaelManaged class which encypts and decrypts files so i replaced the AesManaged class with that. i only have one error left which is with the copyTo because its saying its not a member of the CryptoStream class.
Code:
int main(array<System::String ^> ^args)
{
// Validate command line arguments:
if (args->Length != 4 || String::Compare(args[0], "encrypt", true) && String::Compare(args[0], "decrypt", true)) {
Console::WriteLine("Usage: CryptEx2 <encrypt|decrypt> <password> <input file> <output file>");
return 1;
}
// Call the do-all crypto function:
bool bCryptMode = !String::Compare(args[0], "encrypt", true);
if (!Crypt(args[2], args[3], args[1], bCryptMode)) {
Console::WriteLine("Some sort of error happened during encryption/decryption... :o");
return 1;
}
error: "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) already defined.
should i rename the function to mainBody? will i need to declare it in the h.file too.
also are both files going to be input files and out put files depending on whether i am decrypting or encrypting. e.g when i decrypt the file the file in decrypt mode will be the input file and then when the file is encrypted that will be the output file and vis versa?
Re: how can i encrypt a file?
Quote:
Originally Posted by
katy_price
i found the RijndaelManaged class which encypts and decrypts files so i replaced the AesManaged class with that.
RijndaelManaged is a really good choice. :thumb: And one of the things that are especially nice is that it supports all the features of AesManaged I used as well, so aside from changing the class name the transition requires no code changes at all.
Quote:
i only have one error left which is with the copyTo because its saying its not a member of the CryptoStream class.
To overcome this problem replace this part of the Crypt() function:
Code:
// Process (i.e. encrypt or decrypt) data while copying from input file to output file:
try {
cryptstream->CopyTo(fOutput);
}
catch (...) {
return false;
}
by this:
Code:
// Process (i.e. encrypt or decrypt) data while copying from input file to output file:
try {
const int nBufferSize = 512;
array<Byte> ^abBuffer = gcnew array<Byte>(nBufferSize);
int nBytesRead;
do {
nBytesRead = cryptstream->Read(abBuffer, 0, nBufferSize);
if (!nBytesRead) break;
fOutput->Write(abBuffer, 0, nBytesRead);
} while (nBytesRead == nBufferSize);
}
catch (...) {
return false;
}
You see, it's actually a bit more convoluted, but not really scary either. :)
Quote:
error: "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) already defined.
should i rename the function to mainBody? will i need to declare it in the h.file too.
I assume you get this error when compiling the code from the crypto example as part of your project. Your project already contains a main() function, so you don't need the one from the crypto example at all. Simply delete it. The main() in CryptEx2 didn't do anything besides validating the command line parameters and calling Crypt() at all anyway.
Quote:
also are both files going to be input files and out put files depending on whether i am decrypting or encrypting. e.g when i decrypt the file the file in decrypt mode will be the input file and then when the file is encrypted that will be the output file and vis versa?
The file name parameters to Crypt() are always in the sequence input -> output, regardless of whether you're encrypting or decrypting. So, when encrypting, the plaintext file comes first and when decrypting the encrypted file comes first.
Re: how can i encrypt a file?
Code:
// Process (i.e. encrypt or decrypt) data while copying from input file to output file:
try {
const int nBufferSize = 512;
array<Byte> ^abBuffer = gcnew array<Byte>(nBufferSize);
int nBytesRead;
do {
nBytesRead = cryptstream->Read(abBuffer, 0, nBufferSize);
if (!nBytesRead) break;
fOutput->Write(abBuffer, 0, nBytesRead);
} while (nBytesRead == nBufferSize);
}
catch (...) {
return false;
}
thanks. whats the buffer for, whats happening here? are you creating space for the info read in the input file to put into the output file.
also i have declared the password like so: String ^ good123; But i get this error:string ref is not set to instance of a string. parameter name: s
so i wrote it like String ^ good123 = strPassword; but i get another error. i am not sure whats wrong
bool encrypt = true;
i called the function like so:
Code:
Crypt("authentication methods.txt", "john.txt", good123, encrypt);
Re: how can i encrypt a file?
Quote:
Originally Posted by
katy_price
whats the buffer for, whats happening here? are you creating space for the info read in the input file to put into the output file.
An obvious choice in this situation would have been to transfer the data byte by byte using the ReadByte() and WriteByte() methods. I prefer to move data in mid-size chunks in such situations, though. This is more efficient because the overhead for calling the read and write methods would be incurred for every single byte, while it's only incurred once for every 512 bytes using the buffer.
You also frequently see suggestions around here to transfer files in a single large chunk, but this would fail or be at least really inefficient if the file size is above or close to the total amount of memory available. Though this can be quite efficient for small to mid-size files I, personally don't like it, mainly for historical reasons, because I learned programming on systems that had less memory than it's common today, by several magnitudes.
The buffer size of 512 bytes, BTW, has historical reasons as well. It has been the size of a single disk sector under DOS, under Windows for a long time, and also still on most of the systems nowadays. Large hard disks (in the Tbyte range) may have larger sector sizes nowadays, however.
Quote:
also i have declared the password like so: String ^ good123; But i get this error:string ref is not set to instance of a string. parameter name: s
so i wrote it like String ^ good123 = strPassword; but i get another error. i am not sure whats wrong
If the (tracking handle to the) string actually hasn't been assigned a live string I would have expected that you get a NullReferenceException being thrown. I never have seen an error message looking like what you describe. I think I'll need to see concrete code in order to diagnose the problem.
Re: how can i encrypt a file?
sorry i worked out how to do the password: String ^ strPassword = "length123";
thanks it works. all i need to do now is link the closure of the file to my program so i know when to re-encrypt it. plus i have been looking for a function to open the file instead of system(), i looked at shellExecute() but i got some ambigious error. anyways thanks for your help so far, you've been great :)