Java AES and using my own Key

java aes encryption
java secretkeyspec
java aes 256 encryption decryption example
java aes encryption library
java cipher
aes 256 encryption java source code
aes key generator
encryption and decryption in java source code

I want to encrypt a string using AES with my own key. But I'm having trouble with the bit length of the key. Can you review my code and see what I need to fix/change.

public static void main(String[] args) throws Exception {
    String username = "bob@google.org";
    String password = "Password1";
    String secretID = "BlahBlahBlah";
    String SALT2 = "deliciously salty";

    // Get the Key
    byte[] key = (SALT2 + username + password).getBytes();
    System.out.println((SALT2 + username + password).getBytes().length);

    // Need to pad key for AES
    // TODO: Best way?

    // Generate the secret key specs.
    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

    // Instantiate the cipher
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

    byte[] encrypted = cipher.doFinal((secrectID).getBytes());
    System.out.println("encrypted string: " + asHex(encrypted));

    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
    byte[] original = cipher.doFinal(encrypted);
    String originalString = new String(original);
    System.out.println("Original string: " + originalString + "\nOriginal string (Hex): " + asHex(original));
}

Right now I get an exception "Invalid AES key length: 86 bytes". Do I need to pad my key? How should I do it?

Also do I need to set anything for ECB or CBC?

Thanks

Edit:

As written in the comments the old code is not "best practice". You should use a keygeneration algorithm like PBKDF2 with a high iteration count. You also should use at least partly a non static (meaning for each "identity" exclusive) salt. If possible randomly generated and stored together with the ciphertext.

    SecureRandom sr = SecureRandom.getInstanceStrong();
    byte[] salt = new byte[16];
    sr.nextBytes(salt);

    PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 1000, 128 * 8);
    SecretKey key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec);
    Cipher aes = Cipher.getInstance("AES");
    aes.init(Cipher.ENCRYPT_MODE, key);

===========

Old Answer

You should use SHA-1 to generate a hash from your key and trim the result to 128 bit (16 bytes).

Additionally don't generate byte arrays from Strings through getBytes() it uses the platform default Charset. So the password "blaöä" results in different byte array on different platforms.

byte[] key = (SALT2 + username + password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit

SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

Edit: If you need 256 bit as key sizes you need to download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" Oracle download link, use SHA-256 as hash and remove the Arrays.copyOf line. "ECB" is the default Cipher Mode and "PKCS5Padding" the default padding. You could use different Cipher Modes and Padding Modes through the Cipher.getInstance string using following format: "Cipher/Mode/Padding"

For AES using CTS and PKCS5Padding the string is: "AES/CTS/PKCS5Padding"

Java AES Encryption Decryption Example, For example, the Data Encryption Standard (DES) encryption algorithm is considered highly insecure; Let's see an example of using AES encryption into java program. secretKey = new SecretKeySpec(key, "AES" );. The apache commons codec Base64 methods were used to encode/decode string. The keys were hard coded to prevent anyone to get the keys and use to decrypt string. Below is the example class of EncryptDecrypt.java. Change SECRET_KEY_1 and SECRET_KEY_2 to your own secret keys.

You should use a KeyGenerator to generate the Key,

AES key lengths are 128, 192, and 256 bit depending on the cipher you want to use.

Take a look at the tutorial here

Here is the code for Password Based Encryption, this has the password being entered through System.in you can change that to use a stored password if you want.

        PBEKeySpec pbeKeySpec;
        PBEParameterSpec pbeParamSpec;
        SecretKeyFactory keyFac;

        // Salt
        byte[] salt = {
            (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
            (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
        };

        // Iteration count
        int count = 20;

        // Create PBE parameter set
        pbeParamSpec = new PBEParameterSpec(salt, count);

        // Prompt user for encryption password.
        // Collect user password as char array (using the
        // "readPassword" method from above), and convert
        // it into a SecretKey object, using a PBE key
        // factory.
        System.out.print("Enter encryption password:  ");
        System.out.flush();
        pbeKeySpec = new PBEKeySpec(readPassword(System.in));
        keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

        // Create PBE Cipher
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");

        // Initialize PBE Cipher with key and parameters
        pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

        // Our cleartext
        byte[] cleartext = "This is another example".getBytes();

        // Encrypt the cleartext
        byte[] ciphertext = pbeCipher.doFinal(cleartext);

Java AES 256 Encryption Decryption Example, It uses the same key for encrypting and decrypting, so the sender and the receiver must both know — and use — the same secret key. In below� We are using KeyGenerator Class to generate symmetric encryption keys, we get the KeyGenerator instance by calling the getInstance () method passing the name of the algorithm as a parameter, in our case it is AES. KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;
import java.io.BufferedReader;
import java.io.FileReader;

public class AESFile 
{
private static String algorithm = "AES";
private static byte[] keyValue=new byte[] {'0','2','3','4','5','6','7','8','9','1','2','3','4','5','6','7'};// your key

    // Performs Encryption
    public static String encrypt(String plainText) throws Exception 
    {
            Key key = generateKey();
            Cipher chiper = Cipher.getInstance(algorithm);
            chiper.init(Cipher.ENCRYPT_MODE, key);
            byte[] encVal = chiper.doFinal(plainText.getBytes());
            String encryptedValue = new BASE64Encoder().encode(encVal);
            return encryptedValue;
    }

    // Performs decryption
    public static String decrypt(String encryptedText) throws Exception 
    {
            // generate key 
            Key key = generateKey();
            Cipher chiper = Cipher.getInstance(algorithm);
            chiper.init(Cipher.DECRYPT_MODE, key);
            byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedText);
            byte[] decValue = chiper.doFinal(decordedValue);
            String decryptedValue = new String(decValue);
            return decryptedValue;
    }

//generateKey() is used to generate a secret key for AES algorithm
    private static Key generateKey() throws Exception 
    {
            Key key = new SecretKeySpec(keyValue, algorithm);
            return key;
    }

    // performs encryption & decryption 
    public static void main(String[] args) throws Exception 
    {
        FileReader file = new FileReader("C://myprograms//plaintext.txt");
        BufferedReader reader = new BufferedReader(file);
        String text = "";
        String line = reader.readLine();
    while(line!= null)
        {
            text += line;
    line = reader.readLine();
        }
        reader.close();
    System.out.println(text);

            String plainText = text;
            String encryptedText = AESFile.encrypt(plainText);
            String decryptedText = AESFile.decrypt(encryptedText);

            System.out.println("Plain Text : " + plainText);
            System.out.println("Encrypted Text : " + encryptedText);
            System.out.println("Decrypted Text : " + decryptedText);
    }
}

Encrypting data using my own key (Java in General forum at , Here I would like to encrypt the data using my own key and write the unreadable format data to A cipher like AES-128 would be suitable. Java support many secure encryption algorithms but some of them are weak to be used in security-intensive applications. For example, the Data Encryption Standard (DES) encryption algorithm is considered highly insecure; messages encrypted using DES have been decrypted by brute force within a single day by machines such as the Electronic Frontier Foundation’s (EFF) Deep […]

This wll work.

public class CryptoUtils {

    private  final String TRANSFORMATION = "AES";
    private  final String encodekey = "1234543444555666";
    public  String encrypt(String inputFile)
            throws CryptoException {
        return doEncrypt(encodekey, inputFile);
    }


    public  String decrypt(String input)
            throws CryptoException {
    // return  doCrypto(Cipher.DECRYPT_MODE, key, inputFile);
    return doDecrypt(encodekey,input);
    }

    private  String doEncrypt(String encodekey, String inputStr)   throws CryptoException {
        try {

            Cipher cipher = Cipher.getInstance(TRANSFORMATION);

            byte[] key = encodekey.getBytes("UTF-8");
            MessageDigest sha = MessageDigest.getInstance("SHA-1");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); // use only first 128 bit

            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

            byte[] inputBytes = inputStr.getBytes();     
            byte[] outputBytes = cipher.doFinal(inputBytes);

            return Base64Utils.encodeToString(outputBytes);

        } catch (NoSuchPaddingException | NoSuchAlgorithmException
                | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException | IOException ex) {
            throw new CryptoException("Error encrypting/decrypting file", ex);
       }
     }


    public  String doDecrypt(String encodekey,String encrptedStr) { 
          try {     

              Cipher dcipher = Cipher.getInstance(TRANSFORMATION);
              dcipher = Cipher.getInstance("AES");
              byte[] key = encodekey.getBytes("UTF-8");
              MessageDigest sha = MessageDigest.getInstance("SHA-1");
              key = sha.digest(key);
              key = Arrays.copyOf(key, 16); // use only first 128 bit

              SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

              dcipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            // decode with base64 to get bytes

              byte[] dec = Base64Utils.decode(encrptedStr.getBytes());  
              byte[] utf8 = dcipher.doFinal(dec);

              // create new string based on the specified charset
              return new String(utf8, "UTF8");

          } catch (Exception e) {

            e.printStackTrace();

          }
      return null;
      }
 }

How to Use AES for Encryption and Decryption in Java, He also runs his own blog @ devglan.com Here, we are using AES with CBC mode to encrypt a message as ECB mode is not semantically secure.The IV In the following example we are using 128 bit encryption key. /* AES encryption alogrithm in JAVA */ /* AES alogrithm using password key */ /* developed by Nishanth Thomas Insolutions Global Pvt Ltd Bangalore */ import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Encoder; /* Mode = CipherMode.CBC,-( Cipher-block chaining

MD5, AES, no padding

import static javax.crypto.Cipher.DECRYPT_MODE;
import static javax.crypto.Cipher.ENCRYPT_MODE;
import static org.apache.commons.io.Charsets.UTF_8;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class PasswordUtils {

    private PasswordUtils() {}

    public static String encrypt(String text, String pass) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            Key key = new SecretKeySpec(messageDigest.digest(pass.getBytes(UTF_8)), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(ENCRYPT_MODE, key);

            byte[] encrypted = cipher.doFinal(text.getBytes(UTF_8));
            byte[] encoded = Base64.getEncoder().encode(encrypted);
            return new String(encoded, UTF_8);

        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            throw new RuntimeException("Cannot encrypt", e);
        }
    }

    public static String decrypt(String text, String pass) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            Key key = new SecretKeySpec(messageDigest.digest(pass.getBytes(UTF_8)), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(DECRYPT_MODE, key);

            byte[] decoded = Base64.getDecoder().decode(text.getBytes(UTF_8));
            byte[] decrypted = cipher.doFinal(decoded);
            return new String(decrypted, UTF_8);

        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            throw new RuntimeException("Cannot decrypt", e);
        }
    }
}

AES Encryption and Decryption in Java(CBC Mode), Security Best Practices: Symmetric Encryption with AES in Java and Android Every block will now be encrypted with the key, the IV (also called to be not available install a custom crypto provider like BouncyCastle, but the� 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 u

Security Best Practices: Symmetric Encryption with AES in Java and , Learn how to use the Cipher class to perform cryptographic data encryption and decryption in Java. In this test, we use AES encryption algorithm with a 128-bit key and assert that the decrypted result is equal to the original� UPDATE 2: Turns out your usage of many components of the Java Cipher capabilities are not spot on. Look here at this other SO answer. Java AES and using my own Key. UPDATE 1: To get the 256 bit value down to 128 bits using the example below, here is what you may want to try:

Guide to the Cipher Class, Using the Java Cryptographic Extensions on the main website for The OWASP Generate an AES key using KeyGenerator Initialize the * keysize to 128 bits (16� AES is block cipher capable of handling 128 bit blocks, using keys sized at 128, 192, and 256 bits. Each cipher encrypts and decrypts data in blocks of 128 bits using cryptographic keys of 128-, 192- and 256-bits, respectively.

Using the Java Cryptographic Extensions, The Java platform supports the installation of custom providers that implement Some algorithms such as AES and RSA allow for keys of different lengths, but up and use their own keystores, or even use the user keystore described above. You can use the keytool shipped with the encryption proxy distribution to create AES 128-bit and AES 256-bit encryption keys.

Comments
  • I find your lack of random salt disturbing. Now seriously: in the context of cryptography SALT should be random
  • Haha, funny. I actually do have a random salt, but I cleaned up my code to make my question more clear. That's why the variable is named SALT2. But good reference for others who come across this same problem and like to copy/paste code.
  • This will work, but its hashing my password, then only using the first few bits. There is no better way to do this?
  • There is no better way to generate the key cause AES needs a 128/192/256 bits key. If you don't hash your key and only trim the input it would only use the first 16/24/32 Bytes. So generating a Hash is the only reasonable way.
  • Note that this answer does not use a good key derivation function and is thus not as secure as it should be. See the other answer for a slightly outdated key derivation function - and unfortunately still a static salt.
  • Might I suggest deleting this answer as it is extremely bad practice. A proper key derivation function should be used - at least PBKDF2.
  • Yes, The answer is very bad, as Maarten said years ago. Please check this answer from Cryptography and Key Derivation Function
  • How do I generate my Key with the password using the KeyGenerator? I want to generate the same key based on the password. So I can decrypt the string later.
  • What your talking about is password based encryption not AES. I updated my answer with the sample program for PBE
  • Try and use the PBEKDF2 key generator instead, using string "PBKDF2WithHmacSHA1" for the SecretKeyFactory for more up to date encryption.
  • Actually all the used cryptographic primitives in this answer are outdated, MD5 and DES for sure. Take heed.
  • MD5 and DES are weak cipher suites and should be AVOIDED
  • Maybe add some more explanation text.