2

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.

5
  • 1
    Using key as IV is very bad idea, especially for CTR mode. Do you need to provide key for nodejs as hex encoded? Commented Mar 28, 2019 at 15:50
  • yes, CryptoJS accepts key and iv as hex. Commented Mar 28, 2019 at 16:41
  • Yes, I read same that using key as iv is bad but in current situation what else is going wrong. @gusto2 Thanks. Commented Mar 28, 2019 at 16:43
  • what do you mean by "not able to decrypt"? Do you het an exception (post the stacktrace) or garbled output? Commented Mar 29, 2019 at 7:13
  • CryptoJS returns wordArray as a output. It is giving empty wordArray. No exceptions or errors. Also I have corrected key which is passed to decrypt method. Earlier is was getting passed as word Array [0,256]. Commented Mar 29, 2019 at 9:56

2 Answers 2

1
  • 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).

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks @Topaco. There is some problem with my encoding in java I think, I am using above code but I am getting some random characters (non-readable) as encrypted data. I have checked my imports I am using javax.crypto.
You would have to describe in more detail how the encrypted data are read from the stored file into the JavaScript-code (or more precisely, into the variable encryptedContent). This isn't apparent from your code. Probably the problem is here. The best way is to post the missing code. Or are you trying to determine the encrypted data from the file manually? In this case you mustn't use a text-editor, but a hex-editor, because the hexadecimal representation of the encrypted data is needed.
Actually I was talking about Java code. When I am writing encrypted content to file in java it is getting written with some random characters(many non-keyboard characters).Java code is as it is copied without imports and try catch block. In JavaScript I am intercepting fetch request of file and reading content as text.
The encrypted data consist of bytes with values between 0x00 and 0xFF. If you open the file in a text-editor, then depending on the encoding, alphanumeric characters, special characters, control characters etc. are displayed (which is quite normal). I suppose you mean that. To see the actual (hexadecimal) values, you have to open the file in a hex-editor. Finally, the task is to provide these hexadecimal values in the JavaScript-code so that the decryption can be done.
For further analysis you could proceed step by step: Create the file with the encrypted data with the plaintext from my answer: This is the plain text which needs to be encrypted!. Does the generated file contain the hexadecimal values from my answer: 52F415AB673427C42278E8D6F34C16134D7E3FE7986500980ED4063F3CF51162592CE0F5412CCA0BC2DBAE3F2AEC2D585EE8D7? The next step is to check whether these values are also contained in the JavaScript-code in encryptedContent. I suspect that the problem occurs in the last step.
|
0

Your encryption loop is wrong. I am not sure if it's the cause of your issues, but I'd start with it

read = fileInputStream.read(block);
byte[] writeBuffer = cipher.update(block);

even if you read only partial size of the block, you execute encryption operation over the whole block, you may try

byte[] writeBuffer = cipher.update(block, 0, read);

About using the key as IV, I have to stress that with CTR mode the security will be completely broken.

1 Comment

Thanks for suggestion. This didn't work. Note that, I am able to decrypt in java by using same steps in written in method and just changing mode of cipher instance.

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.