0

I'm working on a project and I need to encrypt a String with AES. The program needs to take be able to either take in a String and output an encrypted string in hex, along with a key, or, using a user-specified key and string, output unencrypted text (that is, the program needs to be able to do both of these things in different instances i.e. I should be able to put in "1234" on my machine and get out "Encrypted text: asdf Key: ghjk"; my friend should be able to put in "Encrypted text: asdf KEy: ghjk" on his and get out "1234" )

Here's what I have so far:

package betterencryption;   

import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.Scanner;

 public class BetterEncryption {

 public static String asHex (byte buf[]) {               //asHex works just fine, it's the main that's
                                                         //giving me trouble
  StringBuffer strbuf = new StringBuffer(buf.length * 2);
  int i;

  for (i = 0; i < buf.length; i++) {
   if (((int) buf[i] & 0xff) < 0x10)
    strbuf.append("0");

   strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
  }

  return strbuf.toString();
 }

 public static void main(String[] args) throws Exception {
   Scanner sc = new Scanner(System.in);
   KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128); 
   SecretKey skey = kgen.generateKey();
   byte[] bytes = skey.getEncoded();
   SecretKeySpec skeySpec = new SecretKeySpec(bytes, "AES");
   Cipher cipher = Cipher.getInstance("AES");
   System.out.print("Do you want to encrypt or unencrypt?\n");/*This is a weird way of doing it,*/
   String choice = sc.next(); char cc = choice.charAt(2);     /*I know, but this part checks to see if*/       
   if(cc=='c'){                                               /*the program is to encrypt or unencrypt*/
   System.out.print("Enter a string to encrypt: ");          /* a string. The 'encrypt' function works.*/
   String message = sc.next();


   cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
   byte[] encrypted = cipher.doFinal((args.length == 0 ? message : args[0]).getBytes());
   System.out.println("Encrypted string: " + asHex(encrypted)+"\nKey: "+asHex(bytes));

   //^This^ section actually works! The code outputs an encrypted string and everything.
   //It's beautiful
   //Unfortunately getting that string back into readable text has been problematic
   //Which is where you guys come in!
   //Hopefully

 }
  if(true){
   System.out.print("\nEnter the encrypted string: "); String encryptedString = sc.next();
   System.out.print("\nEnter the key: "); String keyString = sc.next();
   int len = encryptedString.length();    /*this section converts the user-input string*/
   byte[] encrypted = new byte[len / 2];  /*into an array of bytes*/
   for (int i = 0; i < len; i += 2) {     /*I'm not sure if it works, though*/
   encrypted[i / 2] = (byte) ((Character.digit(encryptedString.charAt(i), 16) << 4)+
           Character.digit(encryptedString.charAt(i+1), 16));
   cipher.init(Cipher.DECRYPT_MODE, skeySpec); /*as you can see, I haven't even begun to implement*/ 
   byte[] original = cipher.doFinal(encrypted);/*a way to allow the user-input key to be used.*/
   String originalString = new String(original);
   System.out.println("\nOriginal string: "+originalString); //I'm really quite stuck.
      //can you guys help?
  } 

 }
   }
}

Well, hopefully someone can help me.

EDIT:

My biggest problems are converting String encryptedString into an sKeySpec and figuring out how to prevent the 'unencrypt' function from giving the user an error saying that the String they input was not properly padded. I know this isn't true because I've tried encrypting a String and then pasting what the encrypted form of it is into the unencryptor only to get an error. The program works fine if I eliminate all the "if" conditions and just have it encrypt a String and then unencrypt it in the same instance; I think this is due to the preservation of keyGen's Random Key

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Eric M.
  • 642
  • 5
  • 16
  • 2
    Can you edit your question to specifically address where you are stuck? It's a bit hard to deduce your question from the comments in the code. – Alan Dec 11 '11 at 20:58

2 Answers2

0

Your problem is this:

KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128); 
SecretKey skey = kgen.generateKey();
byte[] bytes = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(bytes, "AES");

As you've written it, your program is generating a new, random key every time it's run, which is never saved or displayed anywhere. Anything that you're encrypting with this key is effectively impossible to decrypt.

What you'll need to do is come up with some scheme for generating a secret key from the user input, rather than randomly generating it using KeyGenerator. How that scheme will work is up to you.

0

Depending on which AES Variant you use, your key needs to be 128, 192 or 256Bit long. You can use a HashAlgorithm to generate a key with the specific length from the user-input.

String key;
byte[] keydata = hashFunctionToMakeToKeytheRightSize(key);
SecretKeySpec secretKeySpec = new SecretKeySpec(keydata, "AES");

Also see: java-aes-and-using-my-own-key

Community
  • 1
  • 1
HectorLector
  • 1,851
  • 1
  • 23
  • 33