Solved

Create AES encryption key in java ensure Padding is used

Posted on 2011-02-22
6
1,276 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 500 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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
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:
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

708 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now