Osama Aftab
Osama Aftab

Reputation: 7

What is the required size of an AES key in this code?

In the code below I'm initializing the security key from an external class. Is it necessary to use the security key length of 16? Any possibility to use the smaller length byte?

import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class MCrypt {

        private String iv = "fedcba9876543210";
        private IvParameterSpec ivspec;
        private SecretKeySpec keyspec;
        private Cipher cipher;

        private String SecretKey ;

        public MCrypt(String s)
        {
               SecretKey=s;
                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();
                }
        }

        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;
        }
}

Upvotes: 0

Views: 1449

Answers (2)

Robert
Robert

Reputation: 42754

In addition to Duncan's suggested improvements:

Never ever use a password/String directly as a key!

If you want to create a key based on a password use a "Password based key derivation function" - e.g. the standard is PBKDF2 (see for example this question: PBKDF2 with bouncycastle in Java).

Upvotes: 1

Duncan Jones
Duncan Jones

Reputation: 69389

Your key must match one of the permitted lengths for the AES algorithm: 16, 24 or 32 bytes. You cannot use a key smaller than 16 bytes.

Some other comments on your code:

  • Use camelCase for all variables (e.g. secretKey).

  • Avoid using a fixed IV. Generate a random IV each time and store it with the ciphertext.

  • Consider using a padding mode (e.g. AES/CBC/PKCS5Padding) otherwise your input must always be a multiple of 16 bytes.

  • You are calling getBytes() on a string without supplying a charset. This could result in different results on different platforms. Always specify a character set.

Upvotes: 2

Related Questions