[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Create AES encryption key in java ensure Padding is used

Posted on 2011-02-22
6
Medium Priority
?
1,291 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Survive A High-Traffic Event with Percona

Your application or website rely on your database to deliver information about products and services to your customers. You can’t afford to have your database lose performance, lose availability or become unresponsive – even for just a few minutes.

 
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

Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

Question has a verified solution.

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

Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Suggested Courses

649 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