1
votes

Hi I have java code which decrypt the ciphertext encrypted using CryptoJS library(AES). Now i wanted to write the javacode which will encrypt the plaintext again.

Please find the below code.

 try {
        String secret = "René Über";
        String cipherText="U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=";

        byte[] cipherData = Base64.decode(cipherText, Base64.DEFAULT);
        byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes("utf-8"), md5);
        SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");
        IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);

        byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);
        Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] decryptedData = aesCBC.doFinal(encrypted);
        String decryptedText = new String(decryptedData,"utf-8");
        System.out.println("Decrypted "+decryptedText);
//Here I get right plain text as 
//System.out: Decrypted The quick brown fox jumps over the lazy dog.


        Cipher abc=Cipher.getInstance("AES/CBC/PKCS5Padding");
        abc.init(Cipher.ENCRYPT_MODE,key,iv);
        byte[] encryptedData=abc.doFinal(decryptedData);
        String str=Base64.encodeToString(encryptedData,Base64.DEFAULT);


        System.out.println("encrypted "+str);

//Here i want the encrypted text as
// encrypted U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hy//aQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=
//but i receive 
//System.out: encrypted IZ5IDQruC+Cz0pd5krBsIM0KzbM+j4FeO8pgusm60wr6HFPCX+HJpAs5oPssshGjYjl/J5Ew+//eui



    }catch (Exception e)
    {}

When I decrypt the code I get correct Plain Text but when I again encrypt the plain text I didnt get the encrypted text as previous. Please Help.

GenerateKeyAndIV function code:-

 public static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password, MessageDigest md) {

    int digestLength = md.getDigestLength();
    int requiredLength = (keyLength + ivLength + digestLength - 1) / digestLength * digestLength;
    byte[] generatedData = new byte[requiredLength];
    int generatedLength = 0;

    try {
        md.reset();

        // Repeat process until sufficient data has been generated
        while (generatedLength < keyLength + ivLength) {

            // Digest data (last digest if available, password data, salt if available)
            if (generatedLength > 0)
                md.update(generatedData, generatedLength - digestLength, digestLength);
            md.update(password);
            if (salt != null)
                md.update(salt, 0, 8);
            md.digest(generatedData, generatedLength, digestLength);

            // additional rounds
            for (int i = 1; i < iterations; i++) {
                md.update(generatedData, generatedLength, digestLength);
                md.digest(generatedData, generatedLength, digestLength);
            }

            generatedLength += digestLength;
        }

        // Copy key and IV into separate byte arrays
        byte[][] result = new byte[2][];
        result[0] = Arrays.copyOfRange(generatedData, 0, keyLength);
        if (ivLength > 0)
            result[1] = Arrays.copyOfRange(generatedData, keyLength, keyLength + ivLength);

        return result;

    } catch (DigestException e) {
        throw new RuntimeException(e);

    } finally {
        // Clean out temporary data
        Arrays.fill(generatedData, (byte)0);
    }
}
2
Yes It is copy paste from stackoverflow.com/questions/41432896/… I am not lot familiar with cryptography. That link help me to decrypt the ciphertext perfectly.But now I am stuck in encryptionShree
You have already indicated you want to learn crypto. But I'd suggest you user a higher level API for now. They idea is to use crypto to make your system secure, not just to get your code working.Maarten Bodewes
Thanks for suggestion. @ Maarten Bodewes. I will learn crypto to use it, not just for code working.Shree
WARNING to other readers: although above code is correct in the sense that it tries to mimic OpenSSL, the number of iterations is 1, which means that the password based key derivation function is not as secure as it usually should be. This code also lacks authentication of the message and is vulnerable to padding oracle attacks, if those apply. Nowadays OpenSSL command line can also use PBKDF2 with an indicated number of iterations.Maarten Bodewes

2 Answers

2
votes

Your ciphertext has "Salted__<8 byte salt>" at the beginning, which you skip when decrypting. You need to prefix the same in your encryption mode if you want to create OpenSSL compatible ciphertext.

Your encryption code ciphertext seems correct when you view it in a base64 to hex decoder, e.g. the one provided here. However, because each character only contains 64 bits and since the bytes have shifted 16 places (which is not divisible by 3), it just seams that your entire ciphertext is incorrect, while it is just missing 16 bytes at the front.

2
votes

Here posting my working code for android I have used crypto for decryption on the server. Below code is using AES Algorithm

  private static final String key = "aesExamplekey";
  private static final String initVector = "exampleintvec";

public static String encrypt(String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

        byte[] encrypted = cipher.doFinal(value.getBytes());

       // byte[] finalCiphertext = new byte[encrypted.length+2*16];
          return Base64.encodeToString(encrypted, Base64.NO_WRAP);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}`

Server side code asp.net

        public string DecryptStringAES(string cipherText)
    {
        //  var keybytes = Encoding.UTF8.GetBytes("7061737323313233");
        //  var iv = Encoding.UTF8.GetBytes("7061737323313233");
        var keybytes = Encoding.UTF8.GetBytes("aesExamplekey");
        var iv = Encoding.UTF8.GetBytes("exampleintvec");

        var encrypted = Convert.FromBase64String(cipherText);
        var decriptedFromJavascript = DecryptStringFromBytes(encrypted, keybytes, iv);
        return string.Format(decriptedFromJavascript);
    }