0

In my java program I would like to read a .txt file in and encode it afterwards. I know how to read a File in and tried to learn how to encode an array. The problem I have is that I don't know how to combine it, it doesn't work the way I tried it.

Here's the part I can read in my text file with:

public class ReadFile { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("test.txt"); BufferedReader br = new BufferedReader(fr); String zeile = ""; do { zeile = br.readLine(); System.out.println(zeile); } while (zeile != null); br.close(); } } 

In this part I can encrypt and decrypt bytes:

public class Crypt { public static void main(String[] args) { try{ KeyGenerator keygenerator = KeyGenerator.getInstance("DES"); SecretKey myDesKey = keygenerator.generateKey(); Cipher desalgCipher; desalgCipher = Cipher.getInstance("DES"); byte[] text = "test".getBytes("UTF8"); desalgCipher.init(Cipher.ENCRYPT_MODE, myDesKey); byte[] textEncrypted = desalgCipher.doFinal(text); String s = new String(textEncrypted); System.out.println(s); desalgCipher.init(Cipher.DECRYPT_MODE, myDesKey); byte[] textDecrypted = desalgCipher.doFinal(textEncrypted); s = new String(textDecrypted); System.out.println(s); } catch(Exception e) { System.out.println("Error"); } } } 

I thought to read the text file in and put it in a string to encode it, but I think it is way too complex. Is there another way to connect them, or is another way for encoding required?

4
  • You should look a bit at streams (FileInputStream, CipherOutputStream might be the most useful for you) Commented Jul 12, 2017 at 10:20
  • Read the to string, change string to byte array, encrypt bytes... Commented Jul 12, 2017 at 10:22
  • @JeremyGrand what's the difference to the FileReader? Doesn't the FileInputStream just read it in as well? Commented Jul 12, 2017 at 10:50
  • 1
    The fileReader is wrapping a (File)InputStream in order to parse char from bytes. It's counter-productive to parse bytes into chars to then convert them back into bytes. You can open a FileInputStream directly on your file, wrap it with a CipherInputStream that will encrypt every byte read on the fly and then wrap it again with a Reader. That's a more proper way to do things. Commented Jul 12, 2017 at 11:40

2 Answers 2

2

I strongly advise you to use Streams ( see https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html & https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html) rather than directly using a FileReader.

Encryption happens at a lower level (on bytes) than what you're trying to do. Java ciphers offer the convenient CipherInputStream (and CipherOutputStream ) to encrypt byte streams on the fly. It's much cheaper and more scalable than trying to dump a whole file in a single byte[] (moreso because you're decoding and re-encoding the file content).

If you want an example of use, please look at the following snippet :

public static void encrypt(Path inputFile, OutputStream output) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException { // init cipher KeyGenerator keygenerator = KeyGenerator.getInstance("DES"); SecretKey myDesKey = keygenerator.generateKey(); Cipher desalgCipher; desalgCipher = Cipher.getInstance("DES"); desalgCipher.init(Cipher.ENCRYPT_MODE, myDesKey); try(InputStream is = Files.newInputStream(inputFile); // get an IS on your file CipherInputStream cipherIS = new CipherInputStream(is, desalgCipher)){ // wraps input Stream with cipher copyStreams(cipherIS, output); // copyStream is let to the implementer's choice. } } 

And I'll let you figure out how to decrypt.

EDIT :

A common way to communicate encrypted bytes without fear for encoding issues is to encode the raw bytes with base 64.

You can wrap the outputStream with Base64.getEncoder().wrap(os)

Sign up to request clarification or add additional context in comments.

8 Comments

Will you give me a hint for the decrypting part? Do I use the OutputStream as a writer then, or is it reading the encoded part?
@MalteS assuming you've written the encrypted data in a file, the code for decryption is exactly the same, except that you need to init your cipher in decrypt mode.
So I save it as a new file, I guess? Or is it better to override it?
You can use a pair of PipedOutputStream (and PipiedInputStream) to plug the encrypted outputStream to the deciphering inputStream if you want to decrypt right away. I understand you just want to exercise a bit but there is really no meaning to encrypt and decrypt a file in a row. Encryption is pretty much always done for storage or communication. You can plug the OutputStream to a file or to a websocket / servlet and that will cover most of the use for encryption.
I see it is not very senseful. So to save the encrypted file seperatly can I just write the string line; to a file because it is printing it correctly?
|
2

FileReader/FileWriter are the wrong (old utility) classes, as they use the current platform encoding, and a file encrypted on one computer (Greek Windows) would not be decryptable on another computer (Linux server).

Text in java, String, is in Unicode. One cannot (should not) throw arbitrary bytes into a String.

So the following cannot be done

new String(textEncrypted); // Uses the default platform encoding new String(textEncrypted, "UTF-8"); // Probably the bytes are not valid UTF-8 

So do:

Path path = Paths.get("text.txt"); byte[] content = Files.readAllBytes(path); content = encrypt(content); Files.write(path, content); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.