Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 923
mdagis Avatar asked Oct 19 '15 21:10

mdagis


People also ask

Can we use CryptoJS in Java?

CryptoJS implements the same key derivation function as OpenSSL and the same format to put the IV into the encrypted data. So all Java code that deals with OpenSSL encoded data applies. That's the text we started with. And emojis, accents and umlauts work as well.

What encryption does CryptoJS use?

CryptoJS supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a passphrase, then it will generate a 256-bit key. DES is a previously dominant algorithm for encryption, and was published as an official Federal Information Processing Standard (FIPS).

What is JavaScript CryptoJS?

CryptoJS is a growing collection of standard and secure cryptographic algorithms implemented in JavaScript using best practices and patterns. They are fast, and they have a consistent and simple interface.


Video Answer


2 Answers

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.

like image 198
Artjom B. Avatar answered Sep 16 '22 17:09

Artjom B.


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

like image 20
mdagis Avatar answered Sep 16 '22 17:09

mdagis