Java AES encryption and decryption


Praneeth

I want to encrypt and decrypt a password using 128 bit AES encryption and a 16 byte key. There was an error javax.crypto.BadPaddingExceptiondecrypting the value . Do I lose anything when decrypting?

public static void main(String args[]) {
    Test t = new Test();
    String encrypt = new String(t.encrypt("mypassword"));
    System.out.println("decrypted value:" + t.decrypt("ThisIsASecretKey", encrypt));
}

public String encrypt(String value) {
    try {
        byte[] raw = new byte[]{'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'};
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(value.getBytes());
        System.out.println("encrypted string:" + (new String(encrypted)));
        return new String(skeySpec.getEncoded());
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalBlockSizeException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (BadPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

public String decrypt(String key, String encrypted) {
    try {
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(skeySpec.getEncoded(), "AES"));
        //getting error here
        byte[] original = cipher.doFinal(encrypted.getBytes());
        return new String(original);
    } catch (IllegalBlockSizeException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (BadPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}  

error message

encrypted string:�Bj�.�Ntk�F�`�
encrypted key:ThisIsASecretKey
decrypted value:null
May 25, 2012 12:54:02 PM bean.Test decrypt
SEVERE: null
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at bean.Test.decrypt(Test.java:55)
at bean.Test.main(Test.java:24)

In the end I used the following solution based on @QuantumMechanic answer

public class Test {

public String encryptionKey;

public static void main(String args[]) {
    Test t = new Test();
    String encrypt = t.encrypt("mypassword");
    System.out.println("decrypted value:" + t.decrypt(t.encryptionKey, encrypt));
}

public String encrypt(String value) {
    try {
        // Get the KeyGenerator
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(256);
        // Generate the secret key specs.
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        String key = new Base64().encodeAsString(raw);
        this.encryptionKey = key;
        System.out.println("------------------Key------------------");
        System.out.println(key);
        System.out.println("--------------End of Key---------------");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        String encrypt = (new Base64()).encodeAsString(cipher.doFinal(value.getBytes()));
        System.out.println("encrypted string:" + encrypt);
        return encrypt;
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalBlockSizeException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (BadPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

public String decrypt(String key, String encrypted) {
    try {
        Key k = new SecretKeySpec(Base64.getDecoder().decode(key), "AES");
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, k);
        byte[] decodedValue = Base64.getDecoder().decode(encrypted);
        byte[] decValue = c.doFinal(decodedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    } catch (IllegalBlockSizeException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (BadPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

}

Quantum mechanics

If for a block cipher you won't be using a transformation that Cipherincludes a padding scheme , you need to make the number of bytes in the plaintext an integer multiple of the cipher's block size.

So either pad the plain text to a multiple of 16 bytes (i.e. the AES block size) or specify a padding scheme when creating the Cipherobject . For example, you can use:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

Unless you have a good reason not to, use the padding scheme already included in the JCE implementation. They take into account many subtle and extreme situations that you would otherwise have to be aware of and deal with yourself.


Ok, your second question is what you want Stringto use to save the ciphertext.

Generally speaking,

String s = new String(someBytes);
byte[] retrievedBytes = s.getBytes();

Will there be someBytesand retrievedBytesis the same.

If you want/have to save the ciphertext in String, base64 encode the ciphertext bytes first, then construct Stringfrom the base64 encoded bytes . Then when you decrypt, getBytes()you get the base64 encoded bytes from Stringit, then base64 decode them to get the real ciphertext, then decrypt it.

The problem arises because most (all?) character encodings cannot map arbitrary bytes to valid characters. So when creating the code Stringfrom the ciphertext , the Stringconstructor (which converts bytes to characters using the character encoding) essentially has to throw away some bytes because it means nothing to them. So when you get the bytes from the string, they are not the same as the bytes you put into the string.

In Java (and in modern programming in general) you can't assume that one character = one byte unless you absolutely know you're dealing with ASCII. That's why you need to use base64 (or something like that) when you want to build a string from arbitrary bytes.

Related


AES encryption and decryption in Java

death: I'm pretty new to encryption/decryption and have to encrypt some data files, but not entirely sure I'm going about it the right way. Right now, I have a script to encrypt all files that are not included in my repository, but the decryptor is included in

Java AES encryption and decryption

Praneeth I want to encrypt and decrypt a password using 128 bit AES encryption and a 16 byte key. There was an error javax.crypto.BadPaddingExceptiondecrypting the value . Do I lose anything when decrypting? public static void main(String args[]) { Test t

AES encryption and decryption in Java

death: I'm pretty new to encryption/decryption and have to encrypt some data files, but not entirely sure I'm going about it the right way. Right now, I have a script to encrypt all files that are not included in my repository, but the decryptor is included in

AES encryption and decryption in Java

death: I'm pretty new to encryption/decryption and have to encrypt some data files, but not entirely sure I'm going about it the right way. Right now, I have a script to encrypt all files that are not included in my repository, but the decryptor is included in

Java AES encryption and decryption

Praneeth I want to encrypt and decrypt a password using 128 bit AES encryption and a 16 byte key. There was an error javax.crypto.BadPaddingExceptiondecrypting the value . Do I lose anything when decrypting? public static void main(String args[]) { Test t

AES encryption and decryption in Java

death: I'm pretty new to encryption/decryption and have to encrypt some data files, but not entirely sure I'm going about it the right way. Right now, I have a script to encrypt all files that are not included in my repository, but the decryptor is included in

AES encryption and decryption in Java

death: I'm pretty new to encryption/decryption and have to encrypt some data files, but not entirely sure I'm going about it the right way. Right now, I have a script to encrypt all files that are not included in my repository, but the decryptor is included in

AES javascript encryption and Java decryption

Encoder I have implemented RSA encryption in javascrypt and RSA decryption in java, it's just a simple process. But the problem is that I have to encrypt a lot of data in one go, which is not possible with RSA, either I have to split the data to be encrypted (

AES javascript encryption and Java decryption

Encoder I have implemented RSA encryption in javascrypt and RSA decryption in java, it's just a simple process. But the problem is that I have to encrypt a lot of data in one go, which is not possible with RSA, either I have to split the data to be encrypted (

AES javascript encryption and Java decryption

Encoder I have implemented RSA encryption in javascrypt and RSA decryption in java, it's just a simple process. But the problem is that I have to encrypt a lot of data in one go, which is not possible with RSA, either I have to split the data to be encrypted (

AES encryption and decryption using Java

Yogesh D Here's what I'm doing, it might seem a little clunky, but it might help you out. I get one BadPaddingException. Read almost all related topics but couldn't find a proper solution. I am new to encryption decryption programming and need to implement it

AES encryption and decryption using Java

Yogesh D Here's what I'm doing, it might seem a little clunky, but it might help you out. I get one BadPaddingException. Read almost all related topics but couldn't find a proper solution. I am new to encryption decryption programming and need to implement it

AES encryption in JavaScript and decryption in Java

Zenz 0 I have an existing web service that encrypts and decrypts with AES, now I have to encrypt in the same way as Java, but with javascript. I've read all the threads about doing this in javascript but haven't found any useful solution yet. Javascript is alw

AES javascript encryption and Java decryption

Encoder I have implemented RSA encryption in javascrypt and RSA decryption in java, it's just a simple process. But the problem is that I have to encrypt a lot of data in one go, which is not possible with RSA, either I have to split the data to be encrypted (

AES javascript encryption and Java decryption

Encoder I have implemented RSA encryption in javascrypt and RSA decryption in java, it's just a simple process. But the problem is that I have to encrypt a lot of data in one go, which is not possible with RSA, either I have to split the data to be encrypted (

AES encryption in JavaScript and decryption in Java

Zenz 0 I have an existing web service that encrypts and decrypts using AES, now I have to encrypt in the same way as in Java, but in javascript. I've read all the threads about doing this in javascript but haven't found any useful solution yet. Javascript is a

AES encryption using Java and decryption using Java

rkj : I'm making an application that requires Java-based AES encryption and JavaScript-based decryption. I am using the following code as base form for encryption. public class AESencrp { private static final String ALGO = "AES"; private static final byte

AES encryption using Java and decryption using Java

j I'm making an application that requires Java-based AES encryption and JavaScript-based decryption. I am using the following code as base form for encryption. public class AESencrp { private static final String ALGO = "AES"; private static final byte[] k

AES encryption using Java and decryption using Java

rkj : I'm making an application that requires Java-based AES encryption and JavaScript-based decryption. I am using the following code as base form for encryption. public class AESencrp { private static final String ALGO = "AES"; private static final byte

AES encryption/decryption in Node JS similar to Java

PRASHANT Kumar Sharma: I am trying to replicate the Java code for AES encryption and decryption in Node JS . Java code SecretKeySpec skeySpec; String key = "a4e1112f45e84f785358bb86ba750f48"; public void encryptString(String key) throws Exception

Java AES encryption and decryption with static secret

Aaron I have an application that needs to store some secret passwords in a config file like database and ftp passwords/details. I've looked around and found many encryption/decryption solutions using AES, but I can't seem to figure out how to make it work with

Simple AES encryption in PHP, decryption in Java

MH I want to implement a simple and safe way to send some information from a PHP script to a Java client. I've pored over several implementations here, but none have worked so far, and now I'm frustrated. What I ended up doing with some edits was this: PHP: fu

Java simple helloworld AES encryption and decryption

Qwertyzw I got a code snippet from another SO question and modified it a bit, but it doesn't seem to work. Can anyone find out why? Currently printing [B@405e70bc or similar. All I have to do is store the password in encrypted form with the sole purpose of kee

Encryption and decryption AES for all types of files in Java

Insaf Safa: How can I modify this AES encryption code so that it can encrypt and decrypt any kind of file (pdf, docx....) because when I decrypt the pdf file or whatever, I don't get the original file. public EncryptData(File originalFile, File encrypted, Secr

AES 128 encryption in Java decryption (in PHP)

Shanawasi I've been trying to decrypt a string using AES-128 CBC which was originally encrypted using JAVA AES encryption. In Java, PKCS7 padding is used. And I try to encrypt and decrypt using similar PHP code. But I get different results. my java code import