Link to home
Start Free TrialLog in
Avatar of yinnyk
yinnyk

asked on

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

Avatar of for_yan
for_yan
Flag of United States of America image

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.
I of cousre meant : why wouldn't  it work the same way on another machine?
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of yinnyk
yinnyk

ASKER

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
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
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> 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
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

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

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

Why are you trying to coerce the author?

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

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.