Improve company productivity with a Business Account.Sign Up

x
?
Solved

Create AES encryption key in java ensure Padding is used

Posted on 2011-02-22
6
Medium Priority
?
1,325 Views
Last Modified: 2012-05-11
hello,

I have created an AES128 encryption key using the following code.

Can you confirm if this will create the required padding "AES/CBC/PKCS5Padding" also?

I need to ensure padding is part of my key creation & not just a key being created without this.

Accoding to question Ahttp://www.experts-exchange.com/Programming/Algorithms/Q_26823316.html it is included?

Thanks
import java.io.UnsupportedEncodingException;
import sun.misc.BASE64Encoder;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.KeyGenerator;
import java.io.*;
 
public class SecretKeyBuilder {
	public String keyVal;	

    public static void main(String[] args) {

    	SecretKeyBuilder keyBuild=new SecretKeyBuilder();
    	
    	try {
    	  System.out.println("String val = " + keyBuild.keyCreate());
    	} catch (UnsupportedEncodingException e) {
    	    e.printStackTrace();
    	} catch (NoSuchAlgorithmException f) {
    	    f.printStackTrace();
	    } catch (IOException g) {
	    g.printStackTrace();
	    }    	
    }
    
    //create empty constructor
    public SecretKeyBuilder(){
    
    }	
  	
    public String keyCreate() throws UnsupportedEncodingException, NoSuchAlgorithmException, IOException{
    	
     //Create the Secret Key 	
     KeyGenerator generator = KeyGenerator.getInstance("AES");

     generator.init(128);  //Set to use AES 128
     generator.init(new SecureRandom());
     Key key = generator.generateKey();
     byte[] keyBytes = key.getEncoded();

	 // Encode the key to Base64 Encryption
	 BASE64Encoder encoder = new BASE64Encoder();
	 String base64 = encoder.encode(keyBytes);
	 
	 //Write the key to a properties file
	 FileWriter fstream = new FileWriter("test.properties");
     BufferedWriter out = new BufferedWriter(fstream);
     out.write(base64);
     //Close the output stream
     out.close();

	 return base64;
   }	  
  	  	
	
}

Open in new window

0
Comment
Question by:speedygonzalez
  • 4
6 Comments
 
LVL 92

Accepted Solution

by:
objects earned 2000 total points
ID: 34957118
padding is used for the encryption, not the key createion
your code looks fine
0
 
LVL 1

Expert Comment

by:andypwhite
ID: 34959590
As stated above, padding is not determined when a key is generated, but rather as part of a transformation when initialising a Cipher.  Refer to:

Sun JCE Reference

Here's an example I quickly knocked together:

	public void testPadding() {
		try {

			// Obtain an AES key generator
			KeyGenerator generator = KeyGenerator.getInstance("AES");

			// Initialise this Key Generator to generate keys of strength 128bits
			// and inform it to use the Provider supplied SecureRandom implementation
			generator.init(128, new SecureRandom());
			
			// Generate a new key
			SecretKey key = generator.generateKey();

			// Obtain a new cipher for encrypting
			// Use the transformation which states
			//    : AES Encryption
			//    : Cipher Block Chaining mode
			//    : Optimal Asymmetric Encryption Padding with MD5 hashing and MGF1 masking
			Cipher eCipher = Cipher
					.getInstance("AES/CBC/OAEPWithMD5AndMGF1Padding");
			
			// Do the same to get a cipher for decryption
			Cipher dCipher = Cipher
					.getInstance("AES/CBC/OAEPWithMD5AndMGF1Padding");

			// Initialise these ciphers for encrypt/decrypt mode of operation
			// and supply our newly generated key
			eCipher.init(Cipher.ENCRYPT_MODE, key);
			eCipher.init(Cipher.ENCRYPT_MODE, key);
			
			// Test out the ciphers
			String plainText  = "Hello World";
			
			// Convert string to bytes using UTF-8 charset
			byte[] utf8 = plainText.getBytes("UTF8"); 
			
			// Encrypt the bytes
			byte[] encBytes = eCipher.doFinal(utf8);
			
			// Decrypt them
			byte[] decBytes = dCipher.doFinal(encBytes);
			
			// Convert back to a string
			String decText = new String(decBytes, "UTF8");
			
			// Use JUnits assert tests to ensure things worked
			assertEquals(utf8, decBytes);
			assertEquals(plainText, decText);

		} catch (NoSuchAlgorithmException nsae) {
			fail(nsae.getMessage());
		} catch (NoSuchPaddingException nspe) {
			fail(nspe.getMessage());
		} catch (InvalidKeyException ike) {
			fail(ike.getMessage());
		} catch (UnsupportedEncodingException uee) {
			fail(uee.getMessage());
		} catch (IllegalBlockSizeException ibse) {
			fail(ibse.getMessage());
		} catch (BadPaddingException bpe) {
			fail(bpe.getMessage());
		}
	}

Open in new window


*Note: You will need to determine what padding schemes are available based on the Java Provider you are using
*Note: I'm using JUnit test framework here.

Also - you should REALLY AVOID using the sun.misc.BASE64Encoder as it is undocumented, unsupported and, from my experience, unreliable with certain datasets.  A quick google search should find a suitable alternative.


0
 
LVL 1

Expert Comment

by:andypwhite
ID: 34959635
Of course, that code above should say DECRYPT_MODE for the dCipher.init()!

Apologies - I'm on a netbook with no development environment - so couldn't test the above!   I'll recheck later to ensure it's ok.
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
LVL 1

Expert Comment

by:andypwhite
ID: 34959873
And of course, now I've tested it I've realised something else - for any cipher mode that's not ECB you will need to supply an initialisation vector (IV) to the decrypting cipher.  Here's the corrected code - that does work!

	public void testPadding() {
		try {

			// Obtain an AES key generator
			KeyGenerator generator = KeyGenerator.getInstance("AES");

			// Initialise this Key Generator to generate keys of strength 128bits
			// and inform it to use the Java Provider supplied SecureRandom implementation
			generator.init(128, new SecureRandom());
			
			// Generate a new key
			SecretKey key = generator.generateKey();

			// Obtain a new cipher for encrypting
			// Use the transformation which states
			//    : AES Encryption
			//    : Cipher Block Chaining mode
			//    : Optimal Asymmetric Encryption Padding with MD5 hashing and MGF1 masking
			Cipher eCipher = Cipher
					.getInstance("AES/CBC/PKCS5Padding");
			
			// Do the same to get a cipher for decryption
			Cipher dCipher = Cipher
					.getInstance("AES/CBC/PKCS5Padding"); 

			// Initialise these ciphers for encrypt/decrypt mode of operation
			// and supply our newly generated key
			eCipher.init(Cipher.ENCRYPT_MODE, key);
			
			// For modes other than EBC we need to obtain the IV params
			byte[] IV = eCipher.getIV ();
			
			// These IV params are then used to initialise the decryption cipher
			// Note: This IV can be prepended to the beginning of cipher text or
			// passed via other means to a process that decrypts ciphertext
			dCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV));
			
			// Test out the ciphers
			String plainText  = "Hello World";
			
			// Convert string to bytes using UTF-8 charset
			byte[] utf8 = plainText.getBytes("UTF8"); 
			
			// Encrypt the bytes
			byte[] encBytes = eCipher.doFinal(utf8);
			
			// Decrypt them
			byte[] decBytes = dCipher.doFinal(encBytes);
			
			// Convert back to a string
			String decText = new String(decBytes, "UTF8");
			
			// Use JUnits assert tests to ensure things worked
			assertEquals(plainText, decText);

		} catch (NoSuchAlgorithmException nsae) {
			fail(nsae.getMessage());
		} catch (NoSuchPaddingException nspe) {
			fail(nspe.getMessage());
		} catch (InvalidKeyException ike) {
			fail(ike.getMessage());
		} catch (UnsupportedEncodingException uee) {
			fail(uee.getMessage());
		} catch (IllegalBlockSizeException ibse) {
			fail(ibse.getMessage());
		} catch (BadPaddingException bpe) {
			fail(bpe.getMessage());
		} catch (InvalidAlgorithmParameterException iape) {
			fail(iape.getMessage());
		}
	}

Open in new window

0
 

Author Comment

by:speedygonzalez
ID: 34962438
Andypwhite, Apologies, I had not refreshed my page & only seen "objects" posting. I would have shared the points with you if I had seen yours also.

Thanks for the help & sorry for that. It's actually the second time I've done that now with a question!!!
0
 
LVL 1

Expert Comment

by:andypwhite
ID: 34962556
No problem :)
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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.

Join & Write a Comment

The greatest common divisor (gcd) of two positive integers is their largest common divisor. Let's consider two numbers 12 and 20. The divisors of 12 are 1, 2, 3, 4, 6, 12 The divisors of 20 are 1, 2, 4, 5, 10 20 The highest number among the c…
Iteration: Iteration is repetition of a process. A student who goes to school repeats the process of going to school everyday until graduation. We go to grocery store at least once or twice a month to buy products. We repeat this process every mont…
The viewer will learn how to implement Singleton Design Pattern in Java.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

601 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