0

I have the following Javascript code in a web page:

  var decrypt = function (text, password){
    var decipher = crypto.createDecipher('aes-256-cbc',password);
    var dec = decipher.update(text,'hex','utf8');
    dec += decipher.final('utf8');
    return dec;
  }

, and I'm trying to reproduce it using Java, using the following:

static MessageDigest MD5 = null;

static {
    try {
        MD5 = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}


public static String decrypt(String cipherText, String password)
        throws GeneralSecurityException, UnsupportedEncodingException {
    byte[] passwordBytes = hexStringToByteArray(password);
    byte[] keyBytes = MD5.digest(passwordBytes);
    byte[] keyAndPassword = new byte[keyBytes.length + passwordBytes.length];
    System.arraycopy(keyBytes, 0, keyAndPassword, 0, keyBytes.length);
    System.arraycopy(passwordBytes, 0, keyAndPassword, keyBytes.length, passwordBytes.length);
    byte[] ivBytes = MD5.digest(keyAndPassword);
    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec iv = new IvParameterSpec(ivBytes);

    byte[] encrypted = hexStringToByteArray(cipherText);
    Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
    aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
    byte[] decryptedData = aesCBC.doFinal(encrypted);
    return new String(decryptedData, StandardCharsets.UTF_8);
}

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
    }
    return data;
}

which pieces bits from:

, but I get "javax.crypto.BadPaddingException: Given final block not properly padded", on parameters which the JS function decodes correctly.

Note that Given final block not properly padded does not answer this question- as it is obvious that this is a padding problem but the solution is to replicate whatever the JS crypto lib does, which is not well documented.

alex
  • 5,213
  • 1
  • 24
  • 33
  • 1
    Possible duplicate of [Given final block not properly padded](https://stackoverflow.com/questions/8049872/given-final-block-not-properly-padded) – Matt Clark Sep 26 '17 at 20:53
  • @MattClark I have taken a look at that answer, but to solve this specific issue one needs to take into consideration how does the Javascript decipher function work, which that answer doesn't. – alex Sep 26 '17 at 21:10
  • You will need to provide example inputs and outputs. I'm particularly curious about the password string. – President James K. Polk Sep 26 '17 at 23:32
  • Possible useful other post: https://stackoverflow.com/questions/36762098/how-to-decrypt-password-from-javascript-cryptojs-aes-encryptpassword-passphras/36780727#36780727 – TheGreatContini Sep 27 '17 at 02:24
  • See the great Artjom B's answer linked from my previous comment. Look at what he does with the salt to derive the IV. You need to do the same. It looks like the salt should be part of the ciphertext. – TheGreatContini Sep 27 '17 at 02:41
  • @MattClark I don't think that link is relevant. The problem here is peculiarities of how Crypto-JS does its password based encryption. For Alex's code to be compatible with Crypto-JS, he needs to derive the key and IV in a similar fashion that Crypto-JS does. – TheGreatContini Sep 27 '17 at 02:43
  • In any case, after further investigation, using the JS version would be quite enough for my purposes, so I no longer care much about this. If SO has a policy of removing unanswered, not worthwhile questions, this would be a good candidate. – alex Sep 29 '17 at 20:37

0 Answers0