• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Xor file encrypt/decrypt

ArthurGray

Newbie
Aug 31, 2017
13
0
Hello guys, I'm back with a simple question.
I could use some help understanding where's the problem with this piece of code.
Basically it's a method that uses a byte[] password to cycle through a file and xor encrypt it, in a (useless) effort to write bug-free code, I wrote the easiest implementation possible: read a byte, encrypt it, write the result, repeat until no byte is available.
Code:
private void xorFile(String filename, String dest)
{
    try {
        FileInputStream is = new FileInputStream(filename);
        FileOutputStream os = new FileOutputStream(dest);
        int b = is.read();
        int index = 0;
        while(b != -1)
        {
            int c = ((byte)b ^ password[index % password.length]);
            index++;
            os.write(c);
            b = is.read();
        }
        os.flush();
        os.close();
        is.close();
    }
    catch( Exception e )
    {}
}
I don't really understand, the output file ends up being even larger than the input!
I checked both files with a binary viewer, the output file is perfectly fine (xor is working) except for the additional bytes, which consist in a large amount of zeros plus some random bytes at the end.. I don't get where do they come from!
 
Last edited:
Well this line looks dodgy:

Code:
int c = ((byte)b ^ password[index % password.length]);

You declare variable 'c' to be of type int. In Java, an int is 32 bits (4 bytes). This means that the result of your expression, which yields only 1 byte of data, will be padded out to 4 bytes, with 3 bytes of zeroes.

Declare variable c as a byte, and you'll get the result you expect.

In fact you don't even need variable 'c', because you could write

Code:
os.write((byte)b ^ password[index % password.length]);
 
Upvote 0
From the documentation:
void write (int b)
Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.
also is.read returns an integer. The reason is that it needs more than 8 bit to represent the case in which no byte has been read, -1.
I tried it anyway with same result.
I'll add some details: I encrypt a 72KB file obtaining a 76KB where the first 72 are exactly what I would expect, the last 4 are just a pure manifestation of the demon itself.
I also tried to actually catch exceptions but nothing. No exceptions or error logs in logcat.
 
Last edited:
Upvote 0
I am very sorry, I wasn't aware a subsequent method would actually edit my file appending some data.. this is what you get for programming late at night.
Thank you!
I upgraded the script, this should be faster. I'll leave it here since I didn't find a xor file encryptor before writing this, so that perhaps this topic will be of use to someone else (you might consider turning index to long if dealing with large files)
Java:
void xorFile(String filename, String dest, byte[] password) throws IOException
{
        FileInputStream is = new FileInputStream(filename);
        FileOutputStream os = new FileOutputStream(dest);

        byte[] data = new byte[1024*4]; //4 KB buffer
        int read = is.read(data), index = 0;
        while( read != -1 ) {
            for( int k=0; k<read; k++ ) {
                data[k] ^= password[index % password.length];
                index++;
            }
            os.write(data,0,read);
            read = is.read(data);
        }

        os.flush();
        os.close();
        is.close();
}
 
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones