0

I developed an encryption algorithm which takes character by character texts from a .txt file and encrypts it, and then writes it back to another .txt file. The problem is when I read the encrypted file, a character like arrow sign acts as EOF and my loop terminates before the original EOF. Here is my code:

static void ECB_ENCRYPTION(void)
{
    uint8_t i = 0, j = 0, c, buf1[16]


    uint8_t plain_text[16];

    // File pointers for file operations.
    FILE *f, *f1;


    // Encrypts the file [plaintext.txt].
    f = fopen("plaintext.txt", "r");
    f1 = fopen("ciphertext.txt", "w");
    while(1)
    {
        i = 0;
        while(i < 16)
        {
            c = getc(f);
            if(feof(f))
            {
                break;
            }
            else
            {
                plain_text[i] = c;
                ++i;
            }
        }

        if(i != 16)
        {
            while(i < 16)
            {
                plain_text[i] = ' ';
                ++i;
            }
        }

        // Encrypts plain text.
        AES128_ENCRYPT(plain_text, buf1);

        i = 0;
        while(i < 16)
        {
            putc(buf1[i], f1);
            ++i;
        }

        if(feof(f))
            break;

    }

    fclose(f);
    fclose(f1);
}

static void ECB_DECRYPTION(void)
{

    uint8_t i = 0, j = 0, c, buf1[16];

    uint8_t cipher_text[16];

    // File pointers for file operations.
    FILE *f, *f1;

    // Encrypts the file [plaintext.txt].
    f = fopen("ciphertext.txt", "r");
    f1 = fopen("decryptedtext.txt", "w");
    while(1)
    {
        i = 0;
        while(i < 16)
        {
            c = getc(f);
            if(feof(f))
            {
                break;
            }
            else
            {
                cipher_text[i] = c;
                ++i;
            }
        }

        if(feof(f))
            break;

        // Decrypts cipher text.
        AES128_DECRYPT(cipher_text, buf1);

        i = 0;
        while(i < 16)
        {
            putc(buf1[i], f1);
            ++i;
        }

    }

    fclose(f);
    fclose(f1);
}
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Md Omar
  • 17
  • 2
  • 1
    Possible duplicate of [Representing EOF in C code?](http://stackoverflow.com/questions/12389518/representing-eof-in-c-code) – Badda May 15 '17 at 12:01
  • 2
    "Arrow sign" doesn't sound like text. Perhaps you should treat the encrypted file as binary and `fopen` it using `"wb"` and `"rb"`. – Klas Lindbäck May 15 '17 at 12:05
  • 1
    An example of the inputs causing the problems would help. – Horia Coman May 15 '17 at 12:05
  • 1
    Possible duplicate of [Difference between int and char in getchar/fgetc and putchar/fputc?](http://stackoverflow.com/questions/35356322/difference-between-int-and-char-in-getchar-fgetc-and-putchar-fputc) – phuclv May 15 '17 at 12:05
  • I used feof() function to identify the end of my file but it fails at a character like -> arrow and my loop ends before the end of file – Md Omar May 15 '17 at 12:08
  • Follow Klas's advice and open in binary mode. Text mode (often the default in Windows) can be helpful if you are treating a file as text (it smooths over the differences between different systems' ideas of what a "text file" looks like) but is irrelevant when encrypting, when you pretty much want to treat everything as just a collection of bytes. – TripeHound May 15 '17 at 12:11
  • [Why must the variable used to hold getchar's return value be declared as int?](http://stackoverflow.com/q/18013167/995714) – phuclv May 15 '17 at 12:16
  • 1
    Thanks a lot @KlasLindbäck .... your suggestion is right :D How much you helped me I can't just explain .... may god bless you ... I just spend 3 nights and days for only this problem :( – Md Omar May 15 '17 at 12:17
  • Thanks everyone .... :D – Md Omar May 15 '17 at 12:17
  • 1
    Why don't you use the correct type for `c`? `getc` returns an `int`, not an `uint8_t`, i.e. `unsigned char`! Don't wonder if you get unexpected results if you don't follow the rules! – too honest for this site May 15 '17 at 12:38
  • 1
    @KlasLindbäck Thank you ... your suggestion worked and my problem has been solved – Md Omar May 15 '17 at 13:28

2 Answers2

0

That is because an encrypted ascii character can get any binary representation, including nul, EOF, ^Z or whatever. So your resulting encrypted file is no longer a text file. It is now a binary file.

So when creating the encrypted file, open it with "wb" and when reading it, open it with "rb". Also, use binary functions to write (fwrite) and read (fread), not fputc and fegtc.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
0

The use of uint8_t c rather than int c obfuscated the true issue: opening the file in binary vs. text mode. @Klas Lindbäck

int c would have been better. Still OP's use of uint8_t; c = getc(f); if(feof(f)) was almost correct. It fails when an read error occurs.

static void ECB_DECRYPTION(void) {
    uint8_t cipher_text[16];
    uint8_t buf1[16];

    FILE *f = fopen("ciphertext.txt", "rb");  // add 'b'
    assert(f);
    FILE *f1 = fopen("decryptedtext.txt", "wb"); // add 'b'
    assert(f1);
    while(1)
    {
        int c;
        for (unsigned i=0; i<16; i++) {
            c = getc(f);
            if (c == EOF) break;
            cipher_text[i] = (uint8_t) c;
        }

        if(c == EOF) break;  // exit loop on end-of-file or input error

        AES128_DECRYPT(cipher_text, buf1);

        for (unsigned i=0; i<16; i++) {
            putc(buf1[i], f1);
        }
    }

    fclose(f);
    fclose(f1);
}
Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256