Ghouse
Ghouse

Reputation: 516

aes encryption giving error as iv should be 16 bytes long

I am trying to encrypt an integer value which is nearly 40 to 50 characters long. I'm using AES encryption but it is giving me error because the integer value should be 16 byte long. Please see my code below:

public class MCrypt {

private String iv ;//Dummy iv (CHANGE IT!)
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;

private String SecretKey = "khaleed";//Dummy secretKey (CHANGE IT!)

public MCrypt(String firstpar1)
{
    iv=firstpar1;//firstpar1 can be aroung 40-50 characters long

        ivspec = new IvParameterSpec(iv.getBytes());

        keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");

        try {
                cipher = Cipher.getInstance("AES/CBC/NoPadding");
        } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        } catch (NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }
        System.out.println(6666);
}

public byte[] encrypt(String text) throws Exception
{
        if(text == null || text.length() == 0)
                throw new Exception("Empty string");

        byte[] encrypted = null;

        try {
                cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);

                encrypted = cipher.doFinal(padString(text).getBytes());
        } catch (Exception e)
        {                       
                throw new Exception("[encrypt] " + e.getMessage());
        }

        return encrypted;
}

public byte[] decrypt(String code) throws Exception
{
        if(code == null || code.length() == 0)
                throw new Exception("Empty string");

        byte[] decrypted = null;

        try {
                cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

                decrypted = cipher.doFinal(hexToBytes(code));
        } catch (Exception e)
        {
                throw new Exception("[decrypt] " + e.getMessage());
        }
        return decrypted;
}



public static String bytesToHex(byte[] data)
{
        if (data==null)
        {
                return null;
        }

        int len = data.length;
        String str = "";
        for (int i=0; i<len; i++) {
                if ((data[i]&0xFF)<16)
                        str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
                else
                        str = str + java.lang.Integer.toHexString(data[i]&0xFF);
        }
        return str;
}


public static byte[] hexToBytes(String str) {
        if (str==null) {
                return null;
        } else if (str.length() < 2) {
                return null;
        } else {
                int len = str.length() / 2;
                byte[] buffer = new byte[len];
                for (int i=0; i<len; i++) {
                        buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
                }
                return buffer;
        }
}



private static String padString(String source)
{
  char paddingChar = ' ';
  int size = 16;
  int x = source.length() % size;
  int padLength = size - x;

  for (int i = 0; i < padLength; i++)
  {
          source += paddingChar;
  }

  return source;
}
}

Any suggestion will be great.

Upvotes: 1

Views: 1961

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 93948

Don't create your own padding, use "PKCS5Padding" instead of "NoPadding". Make sure your (character) encoding is up to spec and that your IV is random, blocksize in size and included with the cipher text. Use password based encryption if your key is a String.

Upvotes: 1

Related Questions