0

I have researched a lot on this question and finally understood this, that encrypting and decryption using just XOR is not a suggested way of encryption but as it is an academic question I have to do it.

In my scenario I have to save java objects(space delimited strings with xor encryption by a key of our choice) in a file(.txt file) line by line and retrieve them later on if needed. So saving a xor string in a file is not a problem but while decrpytion its getting truncated. Below is a sample similar code which I have implemented for my project.

public class TestingXor {
    private static String XorString(String input){
        String key = "computing";
        Charset charSet = Charset.forName("UTF-8");
        byte[] inputBytes = input.getBytes(charSet);
        byte[] keyBytes = key.getBytes(charSet);
        for(int i=0;i<inputBytes.length;i++){
            inputBytes[i] = (byte)(inputBytes[i] ^ keyBytes[i%keyBytes.length]);
        }
        return (new String(inputBytes,charSet));
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            File testFile = new     File("addressBook.txt");
            Scanner scanObj = new Scanner(testFile);
            String testString = "asd asdasd 07/08/2015 asdasdasd 198546125";
            BufferedWriter writer = new BufferedWriter(new FileWriter(testFile));
            writer.write(XorString(testString));
            writer.close();
            System.out.println(XorString(scanObj.nextLine()));          
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

The above code returns "asd as" where as I need the whole string .If I am not saving the file I am able to encrypt and decrypt properly, but If I am saving the string to a file and retrieving the string from the file and decrypting it does'nt work. I think it is related to saving of the string(\0 getting saved in the middle of the line) but what is the work around this. I dont know the length of the string when I am reading from a file. If this question is already answered you can redirect me to that question.

user3324848
  • 181
  • 1
  • 4
  • 17
  • You need to read the whole file, not a line or even multiple lines, because after XORing you don't have text at all; there are numerous dupes but some are for text so I recommend http://stackoverflow.com/a/326440/2868801 . Also you operate on bytes which won't work for characters that require more than one byte in UTF-8, so in fact your code will work only on ASCII, but your example data is ASCII. – dave_thompson_085 Jul 20 '16 at 21:52

1 Answers1

0

The problem is that you XorString method can return String that contain newlines or other other line separator characters (basically \r\n\u2028\u2029\u0085 and the end of the file. Bad luck for you, your test generated multiple '\r' which makes the Scanner stop looking for the rest of the string.

One way to get away from this is to use some kind of escaping mechanisms. For example, Properties provide such a mechanism, but feel free to implement your own.

Small example:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Properties;

public class TestingXor {
    private static String xorString(String input) {
        String key = "computing";
        Charset charSet = Charset.forName("UTF-8");
        byte[] inputBytes = input.getBytes(charSet);
        byte[] keyBytes = key.getBytes(charSet);
        for (int i = 0; i < inputBytes.length; i++) {
            inputBytes[i] = (byte) (inputBytes[i] ^ keyBytes[i % keyBytes.length]);
        }
        return new String(inputBytes, charSet);
    }

    public static void main(String[] args) throws IOException {
        File testFile = new File("addressBook.txt");
        store(testFile);
        load(testFile);
    }

    private static void load(File file) throws IOException, FileNotFoundException {
        Properties props = new Properties();
        try (InputStream in = new BufferedInputStream(new FileInputStream(file));) {
            props.load(in);
        }
        for (int i = 1; i < props.size() + 1; i++) {
            System.out.println(xorString(props.getProperty("entry-" + i)));
        }
    }

    private static void store(File file) throws IOException, FileNotFoundException {
        Properties props = new Properties();
        String testString = "asd asdasd 07/08/2015 asdasdasd 198546125";
        props.put("entry-1", xorString(testString));
        try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file));) {
            props.store(out, "Some comment");
        }
    }

}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • So is there any other way to retrieve string line by line from a text file apart from scanner or Is there any other format which I need to change my string to save in a file? – user3324848 Jul 20 '16 at 21:29
  • @user3324848 Yes, you need to use some kind of escape mechanisms that avoids new lines for example. Find in my answer, a use of the Properties class that internally performs something similar. – Guillaume Polet Jul 20 '16 at 22:08