Java AES file encryption

Basically I have this code to encrypt and decrypt a file, this works fine when in the same class but i want to run it on two seperate machines. How to get this working?
//RSA - Rivest, Shamir, & Adleman
 
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
 
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
 
import java.security.spec.AlgorithmParameterSpec;
 
public class AESEncrypter
{
	Cipher ecipher;
	Cipher dcipher;
	
	public AESEncrypter(SecretKey key)
	{
		// Create an 8-byte initialization vector
		byte[] iv = new byte[]
		{
			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
		};
		
		AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
		try
		{
			ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			
			// CBC requires an initialization vector
			ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
			dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	// Buffer used to transport the bytes from one stream to another
	byte[] buf = new byte[1024];
	
	public void encrypt(InputStream in, OutputStream out)
	{
		try
		{
			// Bytes written to out will be encrypted
			out = new CipherOutputStream(out, ecipher);
			
			// Read in the cleartext bytes and write to out to encrypt
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0)
			{
				out.write(buf, 0, numRead);
			}
			out.close();
		}
		catch (java.io.IOException e)
		{
		}
	}
	
	public void decrypt(InputStream in, OutputStream out)
	{
		try
		{
			// Bytes read from in will be decrypted
			in = new CipherInputStream(in, dcipher);
			
			// Read in the decrypted bytes and write the cleartext to out
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0)
			{
				out.write(buf, 0, numRead);
			}
			out.close();
		}
		catch (java.io.IOException e)
		{
		}
	}
	
	public static void main(String args[])
	{
		try
		{
			// Generate a temporary key. In practice, you would save this key.
			// See also e464 Encrypting with DES Using a Pass Phrase.
			
			KeyGenerator	kgen	=	KeyGenerator.getInstance("AES");
			kgen.init(128);
			SecretKey key			=	kgen.generateKey();
			
			// Create encrypter/decrypter class
			AESEncrypter encrypter = new AESEncrypter(key);
			
			// Encrypt
			encrypter.encrypt(new FileInputStream("DESTest.txt"),new FileOutputStream("Encrypted.txt"));
			// Decrypt
			encrypter.decrypt(new FileInputStream("Encrypted.txt"),new FileOutputStream("Decrypted.txt"));
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}

Open in new window

yinnykAsked:
Who is Participating?
 
objectsConnect With a Mentor Commented:
you need to use the same SecretKey for both. You save your SecretKey to a file to achieve this
0
 
for_yanCommented:
That is difficult to understand, wha you mean by running it on two separate machines?
You use, say  RMI (Remote Method Invocation).

If it works on one machine, why would it work the same way on another machine?
Please, elaborate.
0
 
for_yanCommented:
I of cousre meant : why wouldn't  it work the same way on another machine?
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
yinnykAuthor Commented:
Sorry not clear, i want to seperate it into two classes so one will encrypt a file and the other will decrypt the file. also i was sent this code from a friend and cant get it working
0
 
for_yanCommented:
In order to run on two machines you don't need to separate it into two classe - just use one ecnryption
method on one machine decryption  on another
0
 
for_yanCommented:
Seems to work fine for me without any changes
(I only remaned to Encryptor class with "o" instead of "e" as
I made mistake in the calss name, but otherwise used your code)

//RSA - Rivest, Shamir, & Adleman

import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;

import java.security.spec.AlgorithmParameterSpec;

public class AESEncryptor
{
	Cipher ecipher;
	Cipher dcipher;

	public AESEncryptor(SecretKey key)
	{
		// Create an 8-byte initialization vector
		byte[] iv = new byte[]
		{
			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
		};

		AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
		try
		{
			ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

			// CBC requires an initialization vector
			ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
			dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	// Buffer used to transport the bytes from one stream to another
	byte[] buf = new byte[1024];

	public void encrypt(InputStream in, OutputStream out)
	{
		try
		{
			// Bytes written to out will be encrypted
			out = new CipherOutputStream(out, ecipher);

			// Read in the cleartext bytes and write to out to encrypt
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0)
			{
				out.write(buf, 0, numRead);
			}
			out.close();
		}
		catch (java.io.IOException e)
		{
		}
	}

	public void decrypt(InputStream in, OutputStream out)
	{
		try
		{
			// Bytes read from in will be decrypted
			in = new CipherInputStream(in, dcipher);

			// Read in the decrypted bytes and write the cleartext to out
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0)
			{
				out.write(buf, 0, numRead);
			}
			out.close();
		}
		catch (java.io.IOException e)
		{
		}
	}

	public static void main(String args[])
	{
		try
		{
			// Generate a temporary key. In practice, you would save this key.
			// See also e464 Encrypting with DES Using a Pass Phrase.

			KeyGenerator	kgen	=	KeyGenerator.getInstance("AES");
			kgen.init(128);
			SecretKey key			=	kgen.generateKey();

			// Create encrypter/decrypter class
			AESEncryptor encrypter = new AESEncryptor(key);

			// Encrypt
			encrypter.encrypt(new FileInputStream("DESTest.txt"),new FileOutputStream("Encrypted.txt"));
			// Decrypt
			encrypter.decrypt(new FileInputStream("Encrypted.txt"),new FileOutputStream("Decrypted.txt"));
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}

Open in new window

DESTest.txt
Encrypted.txt
Decrypted.txt
0
 
for_yanConnect With a Mentor Commented:
You can use the same class - just communicate secret key to the second run
and use one method on one machine and another method on another - you don't
need to split the program
0
 
objectsCommented:
> Sorry not clear, i want to seperate it into two classes so one will encrypt a file and the other will decrypt the file. also i was sent this code from a friend and cant get it working

yes and to do that you need to share the SecretKey
you don't actually need to split it into two classes at all. Just as easy for both to use the same class
0
 
objectsCommented:
Instead of splitting into 2 classes, just change your main to have option of encrypt or dcrypt
for example using a command line option


                  if (args[0].equals("encrypt")) {
                        // Encrypt
                        encrypter.encrypt(new FileInputStream("DESTest.txt"),new FileOutputStream("Encrypted.txt"));
                  } else {
                        // Decrypt
                        encrypter.decrypt(new FileInputStream("Encrypted.txt"),new FileOutputStream("Decrypted.txt"));
                  }

And change it to load the SecretKey as I suggested earlier
0
 
for_yanCommented:

THis code does the same thing as my (and yours) perevious code above but
it also creates key.bin file which you'll need to transfer to another machine

I actually split it for you within one main method - it encodes the key, writes to the file, then read from the file
and decodes it

//RSA - Rivest, Shamir, & Adleman

import java.io.*;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;

import java.security.spec.AlgorithmParameterSpec;

public class AESEncryptor
{
	Cipher ecipher;
	Cipher dcipher;

	public AESEncryptor(SecretKey key)
	{
		// Create an 8-byte initialization vector
		byte[] iv = new byte[]
		{
			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
		};

		AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
		try
		{
			ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

			// CBC requires an initialization vector
			ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
			dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	// Buffer used to transport the bytes from one stream to another
	byte[] buf = new byte[1024];

	public void encrypt(InputStream in, OutputStream out)
	{
		try
		{
			// Bytes written to out will be encrypted
			out = new CipherOutputStream(out, ecipher);

			// Read in the cleartext bytes and write to out to encrypt
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0)
			{
				out.write(buf, 0, numRead);
			}
			out.close();
		}
		catch (java.io.IOException e)
		{
		}
	}

	public void decrypt(InputStream in, OutputStream out)
	{
		try
		{
			// Bytes read from in will be decrypted
			in = new CipherInputStream(in, dcipher);

			// Read in the decrypted bytes and write the cleartext to out
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0)
			{
				out.write(buf, 0, numRead);
			}
			out.close();
		}
		catch (java.io.IOException e)
		{
		}
	}

	public static void main(String args[])
	{
		try
		{
			// Generate a temporary key. In practice, you would save this key.
			// See also e464 Encrypting with DES Using a Pass Phrase.

			KeyGenerator	kgen	=	KeyGenerator.getInstance("AES");
			kgen.init(128);
			SecretKey key			=	kgen.generateKey();

			// Create encrypter/decrypter class
			AESEncryptor encrypter = new AESEncryptor(key);

byte[] encoded = key.getEncoded();




FileOutputStream fos = new FileOutputStream("key.bin");
fos.write(encoded);
            fos.close();






			// Encrypt
			encrypter.encrypt(new FileInputStream("DESTest.txt"),new FileOutputStream("Encrypted.txt"));

            File file = new File("key.bin");
byte[] fileBArray = new byte[(int)file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(fileBArray);
            fis.close();

            key = new SecretKeySpec(fileBArray, "AES");


			// Decrypt
			encrypter.decrypt(new FileInputStream("Encrypted.txt"),new FileOutputStream("Decrypted.txt"));
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}

Open in new window

0
 
for_yanCommented:
Is it possible to know what was the motivation for this objection?
0
 
for_yanCommented:
Mod_MarlEE,

Why are you trying to coerce the author?

It should be their decision, not yours.
And they already made the decision.
0
 
for_yanCommented:

Mod_MarlEE,
The actual solution to this question (and which may be interesting to the thirrd party reader) is of course
neither http:#35717615 nor even http:#35717652, which both contain no more than trivial statements.
The solution which I'm sure author appreciated by his/her choice ( they just didn't pay attention which particular post to accept),
and which required real work and attention and ultimately helped the asker was the code http:#35717684 which showed how to implement the solution. That's what it is if you choose to to stick to the essence of the matter, not to sheer formality.
If I were you, I'd change the solution to  http:#35717684 (for the sake of someone who may want to benefit from this question in future)
and with that close this distracting issue. I'm sure author would not object to such change.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.