1

I copied this code from here and modified it, but then as I've read along AES I've noticed that this is using 128 since the number of key characters are only 16, now how do I make it so that it will be AES 256, though I've also read somewhere that java does not primarily allow AES 256 and only limits to AES 128, and that you need to do some more configuration for it to happen, but I am not that sure if what he said there was true and if how do I proceed with those changes. This is also my first time handling AES.

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;

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

import org.apache.commons.codec.binary.Base64;



public class AES {  
    private static SecretKeySpec secretKey ;
    private static byte[] key ;  
    private static String decryptedString;
    private static String encryptedString;

    public static void setKey(String myKey){ 
        MessageDigest sha = null;
        try {
                key = myKey.getBytes("UTF-8");

                sha = MessageDigest.getInstance("SHA-1");
                key = sha.digest(key);
        key = Arrays.copyOf(key, 16); // use only first 128 bit

       // System.out.println(new String(key,"UTF-8"));
            secretKey = new SecretKeySpec(key, "AES");


        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
        }
    }

    public static String getDecryptedString() {
        return decryptedString;
    }

    public static void setDecryptedString(String decryptedString) {
        AES.decryptedString = decryptedString;
    }

    public static String getEncryptedString() {
        return encryptedString;
    }

    public static void setEncryptedString(String encryptedString) {
        AES.encryptedString = encryptedString;
    }

    public static String encrypt(String initVector, String strToEncrypt) throws InvalidAlgorithmParameterException
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);


            setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));

        }
        catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e)
        {

            System.out.println("Error while encrypting: "+e.toString());
        }
        return null;

    }

    public static String decrypt(String initVector, String strToDecrypt) throws InvalidAlgorithmParameterException, UnsupportedEncodingException
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
            setDecryptedString(new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt))));

        }
        catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e)
        {

            System.out.println("Error while decrypting: "+e.toString());

        }
        return null;
    }


    public static void main(String args[]) throws InvalidAlgorithmParameterException, UnsupportedEncodingException
    {
                String initVector = "Bw/+ctBXLE4=@f9t"; // 16 bytes IV
                final String strToEncrypt = "12345657";
                final String strPssword = "ViK#@Uef$#!BZFgAUW6qZiudgoQ==";
                AES.setKey(strPssword);

                AES.encrypt(initVector, strToEncrypt.trim());

                System.out.println("String to Encrypt: " + strToEncrypt); 
                System.out.println("Encrypted: " + AES.getEncryptedString());

                final String strToDecrypt =  AES.getEncryptedString();
                AES.decrypt(initVector, strToDecrypt.trim());

                System.out.println("String To Decrypt : " + strToDecrypt);
                System.out.println("Decrypted : " + AES.getDecryptedString());



    }

}
makingitwork
  • 149
  • 2
  • 9
  • 2
    It's bad practice to generate your AES key using a SHA1 hash of a password. If you really need to use password - use a algorithm designed for this . Take a look here: [Java 256-bit AES Password-Based Encryption](http://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption) – Ebbe M. Pedersen Nov 19 '15 at 15:14
  • 1
    As a prerequisite, you should install the [unlimited strength policy files](https://stackoverflow.com/questions/1179672/). – f_puras Nov 19 '15 at 15:15
  • @f_puras what is that a prerequisite for? – makingitwork Nov 19 '15 at 15:24
  • @EbbeM.Pedersen thanks for the input, I'll take a look at it and can I ask you if I don't understand something. – makingitwork Nov 19 '15 at 15:35
  • @EbbeM.Pedersen I don't really understand what this part is for: `/* Derive the key, given password and salt. */ SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(password, salt, 65536, 256); SecretKey tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); ` and how do you generate the proper salt and password? – makingitwork Nov 19 '15 at 15:41
  • @makingitwork Read [PKCS#5](https://tools.ietf.org/html/rfc2898#section-5.2) to understand what it is about - it's basically a *secure* replacement for your `setKey` method. But I think the answer does contain enough information - the salt is a byte array with random values. You can also use 32 bytes generated using `SecureRandom` as key, but you would have to manage that key somehow. – Maarten Bodewes Nov 19 '15 at 17:25
  • @makingitwork Vanilla java installations come with crippled *export grade* encryption abilities, as mentioned in your question. You can check it: If `javax.crypto.Cipher.getMaxAllowedKeyLength("RC5") > 128` you have the unrestricted policy files active. – f_puras Nov 20 '15 at 08:25
  • @f_puras That would be slightly obscure, I would opt for `"AES"` and `Integer.MAX_VALUE` to verify if you have unrestricted crypto. – Maarten Bodewes Nov 21 '15 at 10:33
  • @MaartenBodewes Took it from [Checking if Unlimited Cryptography is available](http://stackoverflow.com/a/8607735/1606632). Sorry for not linking it right away, but I first thought I read it somewhere else. If you deem it obscure, you maybe should add a comment there. – f_puras Nov 21 '15 at 21:22
  • 1
    @f_puras I've added an answer and explained why the current answer is not optimal. Thanks for pointing me in that direction. – Maarten Bodewes Nov 22 '15 at 11:54
  • @makingitwork Are you in business now? Because it's easy to extend the `setKey` method to be able to use AES-256 **but it would not offer 256 bit security**. The answer pointed at in the first comment would be a secure replacement. I think it would be more wise to delete this answer; answering that you should look at another answer is not really how SO should work. – Maarten Bodewes Nov 22 '15 at 11:58

0 Answers0