I'm having trouble encrypting data and then writing it out to a text file. First of all, the program I am working on is a question and answer board. A user inputs a subject and a question via an html form, that data is then placed together in a string and then encrypted. I put one "\n" at the end of each encrypted message and write that to the file. The messages are then read in from the data file line by line, each message decrypted and printed to the screen. Sometimes when the encrypted data gets written to the file, it inserts newlines where I don't have any. This usually only happens when it is a long message. The problem is, when I read the data back in, the message is broken across two (or more) lines, when the program tries to decrypt the message, it only has part of the encrypted data for that particular message.
Here is the code block that encrypts the message and writes it to the file:
open (fileOUT, ">>data/messages.dat") || die "Can not write to file";
flock(fileOUT,2);
seek(fileOUT,0,2);
sub encryptMsg() {
my $message = $quest_subj . "\-break\-" . $full_quest . "\-break\-" . $user;
local($/) = undef;
my $enc_msg = RC4($key, $message);
return $enc_msg;
}
printf fileOUT encryptMsg() . "\n";
close(fileOUT);
This runs on a cgi page that takes the user's question and adds it to the messages.dat file. another page reads in the data from the file line by line. here is the block that reads it:
open (fileIN, "data/messages.dat");
my @msg_dat = <fileIN>;
close(fileIN);
my $i = 0;
foreach my $inc (@msg_dat) {
my (@dec_msg, @replies);
chop($inc);
$inc = RC4($key, $inc);
($dec_msg[0], $dec_msg[1], $dec_msg[2], @replies) = split(/\-break\-/, $inc);
if ($_[0] >= 2) {
print qq(<input type="checkbox" name="checker" value=$i>\n);
}
print qq(<a href="fullmessage.cgi?msg_id=$i" target=1>$dec_msg[0]</a> - posted by
$dec_msg[2]<br>\n);
if ($replies[0] ne "") {
foreach my $reply (@replies) {
print qq($reply<br>\n);
}
}
I use a foreach loop to cycle though the array and decrypt each message. I chop the $inc variable prior to decryption. The message is then split (using the "-break-" tag seen above as a delimeter) into the subject, actual message, and username of the person who posted the message.
I've tried several solutions that were on message boards or online tutorials. Here are some things I've tried so far:
- read the entire file into one string by doing local($/) = undef; before reading the file in with $full_msg = <fileIN>;, then breaking the string up using the split function and a tag like "-endmsg-" as a delimeter. This did not solve the problem because removing that newline character prior to reading the file jumbles up the encrypted data (I hope that makes sense).
- using local($/) = undef before encrypting the data. This seemed to provide some help. The problem was less frequent, but still present. I'm still using this as you can see in the code above.
- when adding a new message to the messages.dat file, read the full file in first, decrypt it, append the new message, encrypt that, and then write the whole thing to messages.dat (overwriting). This just seemed to needlessly complicate things. the encryption was still adding newlines.
I must be crazy for trying all of this and still not figuring it out. I just can't figure out what is causing the problem. Is it the RC4 algorithm? Is it the way I am writing the encrypted string to the file? Is it the way I am reading it? Is it something else all together? Would the key I'm using cause the problem? I'm left now with the options of moving away from writing to a file and inputting the data to a mysql database. If I did that, I could simply extract each element from the table, record by record, newlines in the message itself would not cause a problem. Or leaving encryption out of the program. I'd prefer to do neither, so hopefully someone has a good answer. If any more code blocks or information needs to be provided, let me know. Thanks.
Here is the code block that encrypts the message and writes it to the file:
open (fileOUT, ">>data/messages.dat") || die "Can not write to file";
flock(fileOUT,2);
seek(fileOUT,0,2);
sub encryptMsg() {
my $message = $quest_subj . "\-break\-" . $full_quest . "\-break\-" . $user;
local($/) = undef;
my $enc_msg = RC4($key, $message);
return $enc_msg;
}
printf fileOUT encryptMsg() . "\n";
close(fileOUT);
This runs on a cgi page that takes the user's question and adds it to the messages.dat file. another page reads in the data from the file line by line. here is the block that reads it:
open (fileIN, "data/messages.dat");
my @msg_dat = <fileIN>;
close(fileIN);
my $i = 0;
foreach my $inc (@msg_dat) {
my (@dec_msg, @replies);
chop($inc);
$inc = RC4($key, $inc);
($dec_msg[0], $dec_msg[1], $dec_msg[2], @replies) = split(/\-break\-/, $inc);
if ($_[0] >= 2) {
print qq(<input type="checkbox" name="checker" value=$i>\n);
}
print qq(<a href="fullmessage.cgi?msg_id=$i" target=1>$dec_msg[0]</a> - posted by
$dec_msg[2]<br>\n);
if ($replies[0] ne "") {
foreach my $reply (@replies) {
print qq($reply<br>\n);
}
}
I use a foreach loop to cycle though the array and decrypt each message. I chop the $inc variable prior to decryption. The message is then split (using the "-break-" tag seen above as a delimeter) into the subject, actual message, and username of the person who posted the message.
I've tried several solutions that were on message boards or online tutorials. Here are some things I've tried so far:
- read the entire file into one string by doing local($/) = undef; before reading the file in with $full_msg = <fileIN>;, then breaking the string up using the split function and a tag like "-endmsg-" as a delimeter. This did not solve the problem because removing that newline character prior to reading the file jumbles up the encrypted data (I hope that makes sense).
- using local($/) = undef before encrypting the data. This seemed to provide some help. The problem was less frequent, but still present. I'm still using this as you can see in the code above.
- when adding a new message to the messages.dat file, read the full file in first, decrypt it, append the new message, encrypt that, and then write the whole thing to messages.dat (overwriting). This just seemed to needlessly complicate things. the encryption was still adding newlines.
I must be crazy for trying all of this and still not figuring it out. I just can't figure out what is causing the problem. Is it the RC4 algorithm? Is it the way I am writing the encrypted string to the file? Is it the way I am reading it? Is it something else all together? Would the key I'm using cause the problem? I'm left now with the options of moving away from writing to a file and inputting the data to a mysql database. If I did that, I could simply extract each element from the table, record by record, newlines in the message itself would not cause a problem. Or leaving encryption out of the program. I'd prefer to do neither, so hopefully someone has a good answer. If any more code blocks or information needs to be provided, let me know. Thanks.