1

What would be the equivalent of this JS code in Java, using javax.crypto.xxx?

    encryptString : function encryptString(str, password) {
        var cipher = crypto.createCipher("aes128", password);
        return cipher.update(str, "binary", "base64") +
            cipher.final("base64");
    },

    decryptString : function decryptString(str, password) {
        var desipher = crypto.createDecipher("aes128", password);
        return desipher.update(str, "base64", "binary") +
            desipher.final("binary");
    }

I'll be encoding in JS to decode in Java, and vice versa. Both 'str' and 'password' variables are strings, 'password' being 16 chars long.

Looks like this createCipher(algorithm, password) method uses some method to generate raw key and IV, which is not standard across the board. I think using createCipheriv(algorithm, key, iv) will be a more portable approach. More here: http://nodejs.org/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv I'll update the latest soon.

6
  • There are plenty of examples on the net showing how to decrypt using aes128 - what have you found? Commented Oct 20, 2014 at 8:25
  • I've looked at androidsnippets.com/encryptdecrypt-strings but I got a bit confused by creation of raw key. Commented Oct 20, 2014 at 8:58
  • So does your question really reduce to "how do I create the same key in JavaScript and Java"? It might be helpful to make that point of confusion more explicit in your question. Commented Oct 21, 2014 at 11:44
  • Yes, that's right. I didn't quite understand how JS code worked first. Now I know that those methods will generate key and IV from the password given.How? I don't know. Commented Oct 21, 2014 at 11:55
  • 1
    @n0rm9n What are crypto.createCipher and crypto.createDecipher? What library are you using? I thought you were using CryptoJS, but it doesn't seem to have those functions. Are you using Forge? Commented Oct 21, 2014 at 14:04

2 Answers 2

1

This is how you can encrypt/decrypt in JS and Java using Crypto and javax.crypto respectively.

If you don't care about interoperability of different environment, you can get started pretty quickly using createCypher(algorithm, password) in your JS code, but it is not very portable as you don't know how raw key and initialization vector is derived from the password.

Changing the JS code to use createCipheriv(algorithm, key, iv) instead, will give you a portable encryption/decryption:

    encryptString : function encryptString(str, encryptionKey, iv) {
        var cipher = crypto.createCipheriv('aes-128-cbc', encryptionKey, iv);
        var cipherText = cipher.update(str, 'binary', 'base64');
        var cipherTextRemaining = cipher.final('base64');
        return cipherText + cipherTextRemaining;
    },

    decryptString : function decryptString(str, encryptionKey, iv) {
        var desipher = crypto.createDecipheriv('aes-128-cbc', encryptionKey, iv);
        var desipherText = desipher.update(str, 'base64', 'binary');
        var desipherTextRemaining = desipher.final('binary');
        return desipherText + desipherTextRemaining;
    },

This is the equivalent Java code that does the same thing:

public static String encryptString(String clearText, byte[] key, byte[] initialVector) throws Exception
{
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeySpec secretKeySpecy = new SecretKeySpec(key, "AES");
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpecy, ivParameterSpec);
    byte[] encrypted = cipher.doFinal(clearText.getBytes());
    return new String(Base64.encodeBase64(encrypted, false));
}

public static String decryptString(String cipherText, byte[] key, byte[] initialVector) throws Exception
{
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeySpec secretKeySpecy = new SecretKeySpec(key, "AES");
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec);
    return new String(cipher.doFinal(Base64.decodeBase64(cipherText)));
}
Sign up to request clarification or add additional context in comments.

Comments

0

We had a similar problem. So what we wanted is to encrypt the voucherCode in Java side and send it to front end side. Encryption needed to make the voucher code secure.

Now on front end, a third party java script library requires this voucherCode, such that it should be able to retrieve the actual voucherCode by decryption it.

So here is what we have done

On java side

import javax.xml.bind.DatatypeConverter;

    public class Controller{

     @RequestMapping("voucherCode")
     public String getVoucherCode{
       String voucherCode = voucherService.getVoucherCode()
             return  DatatypeConverter.printBase64Binary(voucherCode.getBytes("UTF-8"))

}
    }

So if we have voucher code as 50%OFF then the above code will send NTAlT0ZG as encoded value for 50%OFF.

Now once we have the encoded value on front end. In javascript we can get the original value by using

window.atob("NTAlT0ZG") // this will return 50%OFF

So this way we can have the enncryption/decryption hand in hand between java and java script.

window object provides two methods for encrypt and decrypt

 window.btoa("50%OFF") // returns NTAlT0ZG
    window.atob("NTAlT0ZG") // return original value as "50%OFF"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.