?
Solved

Java AES file encryption

Posted on 2011-05-08
18
Medium Priority
?
703 Views
Last Modified: 2012-05-11
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

0
Comment
Question by:yinnyk
  • 9
  • 3
13 Comments
 
LVL 47

Expert Comment

by:for_yan
ID: 35717609
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
 
LVL 47

Expert Comment

by:for_yan
ID: 35717613
I of cousre meant : why wouldn't  it work the same way on another machine?
0
 
LVL 92

Accepted Solution

by:
objects earned 1000 total points
ID: 35717615
you need to use the same SecretKey for both. You save your SecretKey to a file to achieve this
0
Put Machine Learning to Work--Protect Your Clients

Machine learning means Smarter Cybersecurity™ Solutions.
As technology continues to advance, managing and analyzing massive data sets just can’t be accomplished by humans alone. It requires huge amounts of memory and storage, as well as high-speed processing of the cloud.

 

Author Comment

by:yinnyk
ID: 35717627
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
 
LVL 47

Expert Comment

by:for_yan
ID: 35717637
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
 
LVL 47

Expert Comment

by:for_yan
ID: 35717648
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
 
LVL 47

Assisted Solution

by:for_yan
for_yan earned 1000 total points
ID: 35717652
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
 
LVL 92

Expert Comment

by:objects
ID: 35717664
> 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
 
LVL 92

Expert Comment

by:objects
ID: 35717673
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
 
LVL 47

Expert Comment

by:for_yan
ID: 35717684

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
 
LVL 47

Expert Comment

by:for_yan
ID: 35756425
Is it possible to know what was the motivation for this objection?
0
 
LVL 47

Expert Comment

by:for_yan
ID: 35772047
Mod_MarlEE,

Why are you trying to coerce the author?

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

Expert Comment

by:for_yan
ID: 35772243

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

Featured Post

Threat Trends for MSPs to Watch

See the findings.
Despite its humble beginnings, phishing has come a long way since those first crudely constructed emails. Today, phishing sites can appear and disappear in the length of a coffee break, and it takes more than a little know-how to keep your clients secure.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The recent Petya-like ransomware attack served a big blow to hundreds of banks, corporations and government offices The Acronis blog takes a closer look at this damaging worm to see what’s behind it – and offers up tips on how you can safeguard your…
This article covers the basics of data encryption, what it is, how it works, and why it's important. If you've ever wondered what goes on when you "encrypt" data, you can look here to build a good foundation for your personal learning.
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
The viewer will learn how to implement Singleton Design Pattern in Java.
Suggested Courses
Course of the Month13 days, 21 hours left to enroll

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question