Looking for some sample Java code that decrypts AES encrypted string. I'm trying to encrypt using Apex's Crypto class and decrypt using Java.

  • 1
    given that the string was encrypted by apex code, i think its reasonable to ask here. – superfell Oct 13 '12 at 2:45
  • @superfell - I'm not sure it matters what encrypted it...it's that user730 needs a Java program to decrypt AES128 encryption, whether it was Apex, C#, Java, etc. that encrtypted would seem to be irrelevant. – Peter Knolle Oct 13 '12 at 13:10
  • 2
    the ins outs of formats, etc all seem relevant there's 6 million options for IV, string convertions etc, i think that your trying to pair up 2 different environments is relevant. (one of which being sfdc) – superfell Oct 13 '12 at 15:51
  • 1
    user730 - ok, Anand - could you edit your question to include Apex code, and the Java code that you've tried, or at least a sample Key/IV/Plaintext/Ciphertext combo so we can try out some Java that might work? – metadaddy Oct 14 '12 at 17:35
up vote 16 down vote accepted

The easiest way is to use the Managed IV methods in crypto which will place the Initialization Vector on the front of your cipherText

So, for this Apex:

String clearText = 'the quick brown fox jumps over the lazy dog';
Blob key = EncodingUtil.base64Decode('mRMjHmlC1C+1L/Dkz8EJuw==');
Blob cipherText = Crypto.encryptWithManagedIV('AES128', key, Blob.valueOf(clearText));
String encodedCipherText = EncodingUtil.base64Encode(cipherText); 
System.debug(encodedCipherText);

Here's the corresponding Java

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.util.Arrays;

public class AESDecrypt {

    private static final String characterEncoding = "UTF-8";
    private static final String cipherTransformation = "AES/CBC/PKCS5Padding";
    private static final String aesEncryptionAlgorithm = "AES";

    public static byte[] decryptBase64EncodedWithManagedIV(String encryptedText, String key) throws Exception {
        byte[] cipherText = Base64.decodeBase64(encryptedText.getBytes());
        byte[] keyBytes = Base64.decodeBase64(key.getBytes());
        return decryptWithManagedIV(cipherText, keyBytes);
    }

    public static byte[] decryptWithManagedIV(byte[] cipherText, byte[] key) throws Exception{
        byte[] initialVector = Arrays.copyOfRange(cipherText,0,16);
        byte[] trimmedCipherText = Arrays.copyOfRange(cipherText,16,cipherText.length); 
        return decrypt(trimmedCipherText, key, initialVector);
    }

    public static byte[] decrypt(byte[] cipherText, byte[] key, byte[] initialVector) throws Exception{
        Cipher cipher = Cipher.getInstance(cipherTransformation);
        SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec);
        cipherText = cipher.doFinal(cipherText);
        return cipherText;
    }

    public static void main(String args[]) throws Exception{
        byte[] clearText = decryptBase64EncodedWithManagedIV("CERcUfcNbCAkVxklXVpMqko2FqhE12iU6eldQ9jpFPUl+uVQXKDCXxtfPQ1hwt9A5fIbt60kdVgyFhb2V40z7w==", "mRMjHmlC1C+1L/Dkz8EJuw==");
        System.out.println("ClearText:" + new String(clearText,characterEncoding));
    }


}

apex crypto uses AES(128/192/256)/CBC/PCKS5Padding. Any standard Cipher example from a java tutorial should do the job. Create the Cipher with the IV, create the SecretKey from your key and the AES strength and doFinal() on the encryption. Thats it.

Sorry abt the formatting. total n00b on these forums...

byte [] encBytes = ...; /* your enc string */
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
byte[] iv = ...; /* your IV */;
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decBytes = cipher.doFinal(encBytes);
String decStr = new String(decBytes);

protected by Community Jan 30 '15 at 13:36

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.