Encrypt and decrypt with Java


Encryption is a very important subject in computer science which developers need to deal with quite often. I already wrote a few years ago an article containing some code to encrypt data with PHP and decrypt it with Java.

I will give you this time the code to encrypt and decrypt data with the same language: Java. Once again, I used a secret key and an initialization vector for the encryption and decryption.

And here it is:

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * This class provides methods to encrypt and decrypt data.
 * @author Stephane Moreau
 */
public class Crypto {
    private static String md5(final String input) throws NoSuchAlgorithmException {
        final MessageDigest md = MessageDigest.getInstance("MD5");
        final byte[] messageDigest = md.digest(input.getBytes());
        final BigInteger number = new BigInteger(1, messageDigest);
        return String.format("%032x", number);
    }

    private Cipher initCipher(final int mode, final String initialVectorString, final String secretKey)
            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
        final SecretKeySpec skeySpec = new SecretKeySpec(md5(secretKey).getBytes(), "AES");
        final IvParameterSpec initialVector = new IvParameterSpec(initialVectorString.getBytes());
        final Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
        cipher.init(mode, skeySpec, initialVector);
        return cipher;
    }

    public String encrypt(final String dataToEncrypt, final String initialVector, final String secretKey) {
        String encryptedData = null;
        try {
            // Initialize the cipher
            final Cipher cipher = initCipher(Cipher.ENCRYPT_MODE, initialVector, secretKey);
            // Encrypt the data
            final byte[] encryptedByteArray = cipher.doFinal(dataToEncrypt.getBytes());
            // Encode using Base64
            encryptedData = (new BASE64Encoder()).encode(encryptedByteArray);
        } catch (Exception e) {
            System.err.println("Problem encrypting the data");
            e.printStackTrace();
        }
        return encryptedData;
    }

    public String decrypt(final String encryptedData, final String initialVector, final String secretKey) {
        String decryptedData = null;
        try {
            // Initialize the cipher
            final Cipher cipher = initCipher(Cipher.DECRYPT_MODE, initialVector, secretKey);
            // Decode using Base64
            final byte[] encryptedByteArray = (new BASE64Decoder()).decodeBuffer(encryptedData);
            // Decrypt the data
            final byte[] decryptedByteArray = cipher.doFinal(encryptedByteArray);
            decryptedData = new String(decryptedByteArray, "UTF8");
        } catch (Exception e) {
            System.err.println("Problem decrypting the data");
            e.printStackTrace();
        }
        return decryptedData;
    }

    public static void main(final String[] args) {
        final String iv = "0123456789123456"; // This has to be 16 characters
        final String secretKey = "Replace this by your secret key";
        final Crypto crypto = new Crypto();

        final String encryptedData = crypto.encrypt("This is a test message.", iv, secretKey);
        System.out.println(encryptedData);

        final String decryptedData = crypto.decrypt(encryptedData, iv, secretKey);
        System.out.println(decryptedData);
    }
}

, , ,


  1. #1 by david on 22 Aug 2013 - 14:26

    I looked for the sun decoder and encoder and ran across this thread:

    http://www.coderanch.com/t/273842/java/java/download-jar-sun-misc-BASE

    Any comments?

  2. #2 by smoreau on 22 Aug 2013 - 23:21

    This is very interesting, thank you.
    I never had any problem because I am using Oracle JVMs in all environments. But it seems that the ‘sun.misc’ package is not part of Java SE API and is not guaranteed to be present in the standard library.
    In that case, it is safer to use the Jakarta Commons Codec API instead (http://jakarta.apache.org/commons/codec/).

  3. #3 by Guest on 30 Jul 2015 - 07:36

    Can you please let me know the value of Secret Key.How/Where can we get.

  4. #4 by smoreau on 30 Jul 2015 - 12:33

    The secret key is a string of your choice. You can put anything you want. For example: “0123456789123456”.

  5. #5 by Samina taj on 27 Aug 2015 - 07:54

    same thing with same key and algo ..how can we implement using javascript.Please help with javascript encryption of the above code

  6. #6 by Tanniru Srinivas on 06 Jan 2016 - 08:21

    Iam getting an exception java.security.InvalidKeyException: Illegal key size

  7. #7 by smoreau on 06 Jan 2016 - 09:18

    To fix this exception, please read the following article:
    http://www.logikdev.com/2010/11/09/illegal-key-size/

  8. #8 by Tanniru Srinivas on 08 Jan 2016 - 06:00

    Hello,

    Can u please tell me that is this is complete MD5 algorithm based Encryption and Decryption application or not ???????

  9. #9 by Gabra23 on 30 Nov 2016 - 10:14

    There is a mistake in this line:
    final SecretKeySpec skeySpec = new SecretKeySpec(md5(secretKey).getBytes(), “AES”);
    Because in md5 function you are returning a hex string representing 128 bits ” return String.format(“%032x”, number);” that string is actualy 32 characters which later in getBytes() methid becomes 32 bytes array.
    To fix this use :
    import javax.xml.bind.DatatypeConverter;
    public static byte[] toByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
    }
    so that your hexsring would be parsed correctly to 128 bits

(will not be published)