Reputation: 7466
I would like to encrypt a text with Bruce Schneier's class that was converted to c++ code by Jim Conger After the encryption I would like to decrypt the encrypted text. To try this out, I am using files for it. I've created a sample project, but the decrypted file isn't contains the same text as the initial file. What can be the problem?
Here's the download link for the blowfish class files.
I've created a Command line tool
project in XCode and changed the main.m
file to main.mm
. Here you can find my contents of the main.mm
file:
#import "blowfish.h"
#include <stdlib.h>
#include <stdio.h>
#define my_fopen(fileptr, filename, mode) \
fileptr = fopen(filename, mode); \
if (fileptr == NULL) { \
fprintf(stderr, "Error: Couldn't open %s.\n", filename); \
exit(1); \
}
const char *input_file_name = "test.txt";
const char *encoded_file_name = "encoded.txt";
const char *decoded_file_name = "decoded.txt";
unsigned char key[] = "thisisthekey";
int main(void) {
FILE *infile, *outfile;
int result, filesize;
const int n = 8; // make sure this is a multiple of 8
const int size = 1;
unsigned char input[n], output[n];
CBlowFish bf;
bf.Initialize(key, sizeof(key)-1); // subtract 1 to not count the null terminator
my_fopen(infile, input_file_name, "rb")
my_fopen(outfile, encoded_file_name, "wb")
filesize = 0;
while (result = fread(input, size, n, infile)) {
filesize += result;
fwrite(output, size, bf.Encode(input, output, result), outfile);
}
fclose(outfile);
fclose(infile);
my_fopen(infile, encoded_file_name, "rb")
my_fopen(outfile, decoded_file_name, "wb")
while (result = fread(input, size, n, infile)) {
bf.Decode(input, output, result);
fwrite(output, sizeof(output[0]), filesize < result ? filesize : result, outfile);
filesize -= result;
}
fclose(outfile);
fclose(infile);
return 0;
}
Upvotes: 0
Views: 2268
Reputation: 11628
You MUST encode/decode corresponding blocks of data. fread() and fwrite() doesn't return the same no. of bytes (result) so your plain-text data blocks and your cipher-text data blocks are not aligned.
Defines the data block length (say 64 bytes) and stick to it when encoding and decoding.
Otherwise use a stream cipher which uses "data blocks" of 1 bytes ;)
Upvotes: 1
Reputation: 182769
You're using a block cipher with padding (look at the source code to CBlowFish::Encode
) to encrypt a stream. You can't do that because the decryption operation will have no way to know what constitutes a padded chunk that it should decrypt.
For example, say you're encrypting "FOOBAR", but you read "FOO" the first time and this encrypts to "XYZZY". Then you encrypt "BAR" to "ABCDE". Your written file will contain "XYZZYABCDE". But is that "XY" "ZZYA" "BCDE"? Or one block, "XYZZYABCDE" or what?
If you want to encrypt a stream, use a stream cipher. Or if you want to cut it into arbitrary blocks, you have to preserve the output block boundaries so you can decrypt the blocks.
Upvotes: 1