mdagis
mdagis

Reputation: 116

Using CryptoJS to encrypt in Javascript and decrypt in Java

I am trying to encrypt something in JavaScript using the google's https://code.google.com/p/crypto-js/#AES exactly as it is if the example. The problem is that where I am trying to decrypt it in Java the result is way different. The only difference that I can see is the padding (CryptoJs uses Pkcs7 whereas java uses Pkcs5) after reading a bit I realized that Pkcs7 and Pkcs5 are basically the same.

Here is a sample of the code that i do the encryption in Javascript:

var crypto = require('./aes.js');
var login = 'ABCD';
var key = crypto.CryptoJS.enc.Hex.parse('0123456789012345');
var ive  = crypto.CryptoJS.enc.Hex.parse('0123456789012345');

var encrypted = crypto.CryptoJS.AES.encrypt(login, key, {iv: ive});
console.log('encrypted msg = ' + encrypted)

This is the code that I am using in Java to decrypt it:

public String decrypt(byte[] cipherText) throws Exception {

    String psk = "0123456789012345";
    String iv = "0123456789012345";
    try {
        String encryptionKey = psk;
        final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
        final SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UTF8), "AES");
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv.getBytes(UTF8)));
        return new String(cipher.doFinal(cipherText), UTF8);
    } catch (BadPaddingException | IllegalBlockSizeException | UnsupportedEncodingException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException ex) {
        LOG.log(Level.SEVERE, ex.getMessage(), ex);
        throw new Exception(ex.getMessage());
    }
}

Do you have any idea why it fails that bad? Is it a different algorithm or do I fail somewhere else?

Upvotes: 5

Views: 13902

Answers (2)

mdagis
mdagis

Reputation: 116

Ok, I found the problem. Instead of passing as a parameter the encrypted I should pass encrypted.ciphertext. I now works perfect.

Upvotes: 2

Artjom B.
Artjom B.

Reputation: 61952

You're not using the same key and IV in CryptoJS and Java. The key and IV in the CryptoJS are too short to be valid, because you're parsing a 16 character string as Hex which results in only 8 bytes, but AES supports only key sizes of 128, 192 and 256 bit.

Use

var key = crypto.CryptoJS.enc.Utf8.parse('0123456789012345');
var ive  = crypto.CryptoJS.enc.Utf8.parse('0123456789012345');

Other considerations:

  • Always use a random IV. Since it doesn't have to be secret, you can prepend it to the ciphertext or send it along in another way.

  • Authenticate the ciphertexts with HMAC or use and authenticated mode like GCM to prevent some attacks such as padding oracle attack.

Upvotes: 6

Related Questions