Rewrite a file content in an existing file.
-
I want to write a new text to an existing file.
void CRYPTO_EncryptFile(QString file) { //firs - open a file QFile fil(file); if (!fil.open(QFile::ReadWrite)) return; simp_crypt.setKey(0x0c2ad4a4acb9f023); //read the file QTextStream txt_str(&fil); QString content = txt_str.readAll(); //encrypt it QString encoded = simp_crypt.encryptToString(content); //write the encrypted data back txt_str.flush(); txt_str << encoded; fil.close(); }
But instead it APPENDS the new text to the file not REWRITES.
What do I miss? -
@jenya7 said in Rewrite a file content in an existing file.:
What do I miss?
txt_str.readAll(); - this sets the file pointer to the end.
-
@Christian-Ehrlicher said in Rewrite a file content in an existing file.:
@jenya7 said in Rewrite a file content in an existing file.:
What do I miss?
txt_str.readAll(); - this sets the file pointer to the end.
So? Wat should I do? This will help?
txt_str.seek(0);
-
@jenya7 said in Rewrite a file content in an existing file.:
This will help?
Trying it out would have been much easier than writing this question here.
-
@jenya7 said in Rewrite a file content in an existing file.:
txt_str.seek(0);
Yes, and no!
It is indeed necessary to do that after reading in order to rewrite from the start.
However the file will retain its original length. And that is likely to be wrong (unless you want to guarantee that the encrypted version will be longer than the source). So you will then need to be sure to truncate the file after writing back to it.
All in all, you may find it simpler to open for read, read all, and close. When ready to write back, open for write (and truncate, that is standard), rewrite whole file, close. Many things do it this way.
-
@JonB said in Rewrite a file content in an existing file.:
@jenya7 said in Rewrite a file content in an existing file.:
txt_str.seek(0);
Yes, and no!
It is indeed necessary to do that after reading in order to rewrite from the start.
However the file will retain its original length. And that is likely to be wrong (unless you want to guarantee that the encrypted version will be longer than the source). So you will then need to be sure to truncate the file after writing back to it.
All in all, you may find it simpler to open for read, read all, and close. When ready to write back, open for write (and truncate, that is standard), rewrite whole file, close. Many things do it this way.
I see. But what is "truncate" ? truncate() method for QString? what's the method argument then?
-
@jenya7
Truncate for the file. If you do not understand about file truncation, do not open a file for ReadWrite!However the file will retain its original length. And that is likely to be wrong (unless you want to guarantee that the encrypted version will be longer than the source). So you will then need to be sure to truncate the file after writing back to it.
Which is why I suggested you might be more comfortable with separate opens: one for reading the file, and close it, a fresh one for writing to the file, and close it.
-
That'll do?
void CRYPTO_EncryptFile(QString file) { //firs - open a file QFile fil(file); if (!fil.open(QFile::ReadOnly)) return; simp_crypt.setKey(0x0c2ad4a4acb9f023); //read the file QTextStream txt_str(&fil); QString content = txt_str.readAll(); fil.close(); //encrypt it QString encrypted = simp_crypt.encryptToString(content); //write the encrypted data back //txt_str.seek(0); //txt_str.flush(); //txt_str << encrypted; if (!fil.open(QFile::WriteOnly)) return; QByteArray ba = encrypted.toLocal8Bit(); char *str = ba.data(); fil.write(str); fil.close(); }
-
@mchinand said in Rewrite a file content in an existing file.:
It looks correct. You should do some more testing (and add some error handling) before trusting it on files you care about. Make sure you can decrypt and get the original contents back exactly with your newly created encrypted file.
I see encrypted data in the file. But decrypt doesn't work.
OMG! Sorry, my bad. It works like a charm.
-
@jenya7 said in Rewrite a file content in an existing file.:
It works like a charm.
great, so if your issue is solved please don't forget to mark your post as such!
-
@jenya7 said in Rewrite a file content in an existing file.:
QByteArray ba = encrypted.toLocal8Bit();
char *str = ba.data();fil.write(str);
That can be simplified:
fil.write(encrypted.toLocal8Bit());
There's no need to search for a pointer since QIODevice already provides an overload to write QByteArray.
-
@jenya7 said in Rewrite a file content in an existing file.:
What if I want to change it - where can I store it?
This is a very complicated question because there is a difference between "Where can I store it?" and "Where should I store it?".
The first question is how you obtain the key. Is it something that is the same for everybody? Should it be installed together with your software? Or does every user create their own key? If every user has their own key you can use QSettings to store it. However, it might be too easy for other users on the same computer to get access to the key which they shouldn't be able to do. As an example SSH private keys are stored in a users home folder and can only be used if file permissions are set only for that user. You could then use QSettings and specify a file in the users folder for storage. I am not sure, though, if you can change file permissions with Qt. One step further would be to not save the key as plain text, but protect it with a password. Have a look at password hashing with a random seed (though here we want to hash the key with the methods usually used for passwords).
You see, the correct approach depends on which level of security you require. BTW, if you change the key in your code you will not be able to decrypt any old files. This is something you should consider...
-
@jenya7
You have several problems!I assume you are using symmetric encryption. That means the same key as used to encrypt is also used to decrypt.
-
Why would you want to change this key?
-
When would you want to change it? If you change it after you have encrypted anything you will need the previous one(s) in order to decrypt. That means you will have to store some history of which keys area associated with which encrypted objects. Not a good idea.
-
Most significantly: If you store the key used externally, anybody who can access that can break all your encryption. You will then spend much time trying to ensure the stored location or content is secure.
-
-
@JonB said in Rewrite a file content in an existing file.:
@jenya7
You have several problems!I assume you are using symmetric encryption. That means the same key as used to encrypt is also used to decrypt.
-
Why would you want to change this key?
-
When would you want to change it? If you change it after you have encrypted anything you will need the previous one(s) in order to decrypt. That means you will have to store some history of which keys area associated with which encrypted objects. Not a good idea.
-
Most significantly: If you store the key used externally, anybody who can access that can break all your encryption. You will then spend much time trying to ensure the stored location or content is secure.
Suppose I provide the app to a user. He wants to set his own key. Another case - the key was busted - he wants to change it. The same situation like with any password - I log to Qt forum with a password but I have an ability to change it.
-
-
@jenya7 said in Rewrite a file content in an existing file.:
Suppose I provide the app to a user. He wants to set his own key.
Then prompt the user to enter a key. Are you then saying you want your program to save that particular key, so that without user intervention it can later decrypt the data itself? Or, are you saying the end user would be prompted to re-enter the key for decryption, in which case you have no need to save it anywhere?
Another case - the key was busted - he wants to change it.
I do not know what "busted" means. If you want to change the key after data has been encrypted, you would first need the original key to decrypt what you have encrypted, only then could you use a new key to re-encrypt.
The same situation like with any password - I log to Qt forum with a password but I have an ability to change it.
This is a quite different situation. The forum requires a password for authorisation, but it has not in any way encrypted the current data with the original password.
-
@JonB said in Rewrite a file content in an existing file.:
@jenya7 said in Rewrite a file content in an existing file.:
Suppose I provide the app to a user. He wants to set his own key.
Then prompt the user to enter a key. Are you then saying you want your program to save that particular key, so that without user intervention it can later decrypt the data itself? Or, are you saying the end user would be prompted to re-enter the key for decryption, in which case you have no need to save it anywhere?
Another case - the key was busted - he wants to change it.
I do not know what "busted" means. If you want to change the key after data has been encrypted, you would first need the original key to decrypt what you have encrypted, only then could you use a new key to re-encrypt.
The same situation like with any password - I log to Qt forum with a password but I have an ability to change it.
This is a quite different situation. The forum requires a password for authorisation, but it has not in any way encrypted the current data with the original password.
I thought about the following scenario:
I provide the app to a user. He has settings.xml file with all system parameters, say I put the key in the file too.
Now from the GUI he can command - "encrypt file_pass" - and the file encrypted. If he wants to change some data like the encryption key - he commands from GUI - "decrypt file_pass" - and file decrypted, he changes the data - and commands - "encrypt file_pass" to encrypt the data back.
In order to issue the command from GUI he has to enter a password.....where should I store the password ? The password can not be hardcoded also - the user wants to change it sometimes.
It always the end of the rope - and the master key is hanging there.Ohhh...Now I see - he can feed the key with the command "encrypt file_pass key". The problem is solved.
Not quite! The app at start up has to decrypt the settings.xml file and parse system parameters from it. So the key should be present and available to the app.
I have to note - it's an autonomous app. A user (technician) come occasionally to check the system or update parameters. -
@jenya7 said in Rewrite a file content in an existing file.:
say I put the key in the file too.
Don't do that. If you just want to obfuscate the password you can qCompress it.
@jenya7 said in Rewrite a file content in an existing file.:
where should I store the password ?
You should not. Store the hash of the password (SHA-512 for example), which is one way function btw., then when user enters the password you compute same hash algo from it and compare the hashes. This is the way.
@jenya7 said in Rewrite a file content in an existing file.:
The app at start up has to decrypt the settings.xml file and parse system parameters from it. So the key should be present and available to the app.
This is often the problem and there are many ways to overcome this, from obfuscation to secure wallets/stores provided by the system but none of it is straightforward (and I might be wrong here but Qt does not provide uniform interface to those for any of the platforms).
Usually one just has to evaluate the effort required to extract the data/value of the data against the effort required to perform such "break in"/extraction. Sometimes just doing qCompress (or other bit manipulation) on the key part of the data is sufficient, sometimes you have to dig in further.