Search code examples
javaencryptioncryptographyaescryptojs

AES encryption in java and decryption in javascript using CryptoJS


I have below code to encrypt some file content in java by using AES/CTR/NOPADDING mode. I am using crypto package of javax. Also I am using same secret key to generate key and iv.

Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");

        byte[] secretKey = Base64.decodeBase64("uQsaW+WMUrjcsq1HMf+2JQ==");

        SecretKeySpec key = new SecretKeySpec(secretKey, "AES");
        IvParameterSpec iv = new IvParameterSpec(secretKey);

        cipher.init(mode, key , iv);

        FileInputStream fileInputStream = new FileInputStream(sourceFilePath);
        FileOutputStream fileOutputStream = new FileOutputStream(destFilePath);

        int read = 0;
        while ((fileInputStream.available()) > 0) {
            byte[] block = new byte[4096];
            read = fileInputStream.read(block);
            byte[] writeBuffer = cipher.update(block);
            fileOutputStream.write(writeBuffer, 0, read);
        }

        byte[] writeBuffer = cipher.doFinal();
        fileOutputStream.write(writeBuffer, 0, writeBuffer.length);

        fileInputStream.close();
        fileOutputStream.close();

I am not able to decrypt encrypted content in javascript by using cryptojs. Here is something I have tried.

var key = CryptoJS.enc.Hex.parse(atob('uQsaW+WMUrjcsq1HMf+2JQ=='));

var decrypted = CryptoJS.AES.decrypt(encryptedContent, key, {
    mode: CryptoJS.mode.CTR,
    iv: key,
    padding: CryptoJS.pad.NoPadding
});

var decryptedText = CryptoJS.enc.Utf8.stringify(decrypted);

Can somebody tell me what I am doing wrong? Or tell me how to do it.

I am able to encrypt and decrypt in java and javascript independently.


Solution

    • In the CryptoJS-documentation is explained which data types and parameters the CryptoJS.decrypt()-method expects and which encoders are available:

      • The key has to be passed to the CryptoJS.decrypt()-method as a WordArray. Since the key-data are Base64-encoded, they can be converted into a WordArray with the CryptoJS.enc.Base64.parse()-method.
      • The ciphertext can be passed to the CryptoJS.decrypt()-method as a WordArray inside a CipherParams-object. The Java-code stores the encrypted data in a file. Assuming that the string encryptedContent contains those data as hex-string (unfortunately, this does not emerge from the posted code, so that an assumption must be made here), they can be converted into a WordArray with the CryptoJS.enc.Hex.parse()-method and wrapped in a CipherParams-object.
      • The CryptoJS.decrypt()-method returns a WordArray which can be converted with the CryptoJS.enc.Utf8.stringify()-method into a string.
    • If the following plain text is contained in the input-file:

      This is the plain text which needs to be encrypted!
      

      the Java-code stores the following byte-sequence (= encrypted data) in the output-file:

      52F415AB673427C42278E8D6F34C16134D7E3FE7986500980ED4063F3CF51162592CE0F5412CCA0BC2DBAE3F2AEC2D585EE8D7
      

      The JavaScript-Code for the decryption is:

      var key = CryptoJS.enc.Base64.parse('uQsaW+WMUrjcsq1HMf+2JQ==');
      
      var encryptedContent = '52F415AB673427C42278E8D6F34C16134D7E3FE7986500980ED4063F3CF51162592CE0F5412CCA0BC2DBAE3F2AEC2D585EE8D7';
      var cipherParams = CryptoJS.lib.CipherParams.create({
          ciphertext: CryptoJS.enc.Hex.parse(encryptedContent)         
      });
      
      var decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
          mode: CryptoJS.mode.CTR,
          iv: key,
          padding: CryptoJS.pad.NoPadding
      });
      
      var decryptedText = CryptoJS.enc.Utf8.stringify(decrypted);
      console.log(decryptedText); 
      

    which displays the original plain text in the console. To run the code above at least CryptoJS-version 3.1.4 is needed (see versions, cdnjs).