Search code examples
cxor

XOR only partially decrypts file


I'm learning C, and it's going slowly because I'm teaching myself. I'm trying to create a small function that reads a file, XOR encrypts it byte by byte, and spits it back out. It seems to work for encryption, but when I decrypt only half of it is legible, the rest is gibberish.

int encrypt_file(void)
{
         //declare variables used
         FILE *src_file_ptr;
         FILE *dst_file_ptr;
         char infilename[96];
         char key[50];
         char outfilename[96];
         char temp_store[50];
         int plen;
 
         printf("Please enter the name of the file to encrypt: ");
         scanf("%s", infilename);
         printf("Please enter the name of the output file: ");
         scanf("%s", outfilename);
         printf("Please enter the key to encrypt the file: ");
         scanf("%s", key);
         plen = strlen(key);
         
         //test for existence of input file
         src_file_ptr = fopen(infilename, "r");
         if (src_file_ptr == NULL)
         {
                 printf("File does not exist!");
                 return 1;
         }       
         
         dst_file_ptr = fopen(outfilename, "a");
         //read and process file 50 bytes at a time
         while(fgets(temp_store, 50, src_file_ptr) != NULL)
         {
                 int i;
                 //XOR n bytes with key
                 for ( i = 0; i < strlen(temp_store); i++)
                 {
                         temp_store[i] = temp_store[i] ^ key[i%plen];
                         fprintf(dst_file_ptr,"%c",temp_store[i]);
                 }
 
         }
         fclose(dst_file_ptr);
         fclose(src_file_ptr);
         return 0;
 
}

int main(void)
{
   encrypt_file();
   return 0;
}

I've researched extensively here on stack overflow, and everything I've found is for XOR encrypting / decrypting set value strings. I'm trying to get it to work dynamically by reading in a file and asking for a password (key) from the user. Any help would be greatly appreciated.


Solution

  • So after much more painful head against the wall, and help from folks here I found the solution.

    int encrypt_file(void)
       {
             //declare variables used
             FILE *src_file_ptr;
             FILE *dst_file_ptr;
             char infilename[96];
             char key[50];
             char outfilename[96];
             char temp_store[50];
             int plen;
     
             printf("Please enter the name of the input file: ");
             scanf("%s", infilename);
             printf("Please enter the name of the output file: ");
             scanf("%s", outfilename);
             printf("Please enter the key to perform encrypt / decrypt: ");
             scanf("%s", key);
             plen = strlen(key);
     
             //test for existence of input file
             src_file_ptr = fopen(infilename, "rb");
             if (src_file_ptr == NULL)
             {
                     printf("File does not exist!");
                     return 1;
             }
     
             dst_file_ptr = fopen(outfilename, "wb");
             //create and initialize iterator
             int i = 0;
             do
             {
                     //variable for new byte
                     char nb;
                     // check for end of file and exit if found
                     if (feof(src_file_ptr))
                             break;
                     //check where iterator is at. If same length as password, reset it.
                     if (i == plen)
                     {
                             i = 0;}
                     //read single character from file, in binary mode
                     char c = fgetc(src_file_ptr);
                     // combine file character with password character using XOR
                     nb = c ^ key[i];
                     //write new character to file as byte
                     fputc(nb, dst_file_ptr);
                     //increment to next letter in password
                     i++;
     
             } while(1);
             fclose(dst_file_ptr);
             fclose(src_file_ptr);
             return 0;
     }
    
    int main(void)
    {
    encrypt_file();
    return 0;
    }
    

    This works perfectly for text files, haven't tried binaries yet but all I needed was for plaintext so far.