Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encrypt and decrypt with AES and Base64 encoding

I have following program for encrypting data.

import java.security.Key;  import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec;  import org.apache.commons.codec.binary.Base64;  public class Test {      private static final String ALGORITHM = "AES";     private static final byte[] keyValue = "ADBSJHJS12547896".getBytes();      public static void main(String args[]) throws Exception {         String encriptValue = encrypt("dude5");         decrypt(encriptValue);      }      /**      * @param args      * @throws Exception      */      public static String encrypt(String valueToEnc) throws Exception {          Key key = generateKey();         Cipher c = Cipher.getInstance(ALGORITHM);         c.init(Cipher.ENCRYPT_MODE, key);          System.out.println("valueToEnc.getBytes().length "+valueToEnc.getBytes().length);         byte[] encValue = c.doFinal(valueToEnc.getBytes());         System.out.println("encValue length" + encValue.length);         byte[] encryptedByteValue = new Base64().encode(encValue);         String encryptedValue = encryptedByteValue.toString();         System.out.println("encryptedValue " + encryptedValue);          return encryptedValue;     }      public static String decrypt(String encryptedValue) throws Exception {         Key key = generateKey();         Cipher c = Cipher.getInstance(ALGORITHM);         c.init(Cipher.DECRYPT_MODE, key);          byte[] enctVal = c.doFinal(encryptedValue.getBytes());         System.out.println("enctVal length " + enctVal.length);          byte[] decordedValue = new Base64().decode(enctVal);          return decordedValue.toString();     }      private static Key generateKey() throws Exception {         Key key = new SecretKeySpec(keyValue, ALGORITHM);         return key;     }  } 

Here I am getting the following out put with exception?

valueToEnc.getBytes().length 5 encValue length16 encryptedValue [B@aa9835 Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher     at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)     at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) 

Can some one explain me the cause? Why its only saying when decrypting that length should be 16. Doesn't it convert to 16 as like encrypting with the doFinal method.

And as the exception says "how to decrypting without padded cipher?"

like image 372
Harshana Avatar asked Oct 17 '10 18:10

Harshana


People also ask

Is Base64 encoding the same as encryption?

Base64 is not encryption -- it's an encoding. It's a way of representing binary data using only printable (text) characters.

Is AES 256 Crackable?

AES 256 is virtually impenetrable using brute-force methods. While a 56-bit DES key can be cracked in less than a day, AES would take billions of years to break using current computing technology. Hackers would be foolish to even attempt this type of attack. Nevertheless, no encryption system is entirely secure.

How do I decrypt with Base64?

To decode with base64 you need to use the --decode flag. With encoded string, you can pipe an echo command into base64 as you did to encode it. Using the example encoding shown above, let's decode it back into its original form. Provided your encoding was not corrupted the output should be your original string.


2 Answers

Your Order for encrypt: getBytes, encrypt, encode, toString
Your Order for decrypt(Wrong*): getBytes, decrypt, decode, toString

Two problems:

  1. As someone already mentioned you should reverse the order of operations for decryption. You are not doing that.
  2. encrypt gives you 16 bytes, encode 24 bytes, but toString gives 106 bytes. Something to do with invalid chars taking up additional space.

Note: Also, you don't need to call generateKey() twice.

Fix problem #1 by using the reverse order for decryption.
Correct order for decrypt: getBytes, decode, decrypt, toString

Fix problem #2 by replacing xxx.toString() with new String(xxx). Do this in both the encrypt and decrypt functions.

Your decrypt should look like this:

c.init(Cipher.DECRYPT_MODE, key) val decodedValue = new Base64().decode(encryptedValue.getBytes()) val decryptedVal = c.doFinal(decodedValue) return new String(decryptedVal) 

This should give you back "dude5"

like image 89
Babu Srinivasan Avatar answered Sep 25 '22 13:09

Babu Srinivasan


The line

String encryptedValue = encryptedByteValue.toString(); 

is the problem. The type of encryptedByteValue is byte[] and calling toString on it isn't what you want to do there. Instead try

String encryptedValue = Base64.getEncoder().encodeToString(encValue); 

Then use Base64.decodeBase64(encryptedValue) in decrypt. You must do that prior to attempting to decrypt though. You must undo the operations in the reverse order of the encrypt method.

like image 39
laz Avatar answered Sep 25 '22 13:09

laz