Search code examples
javanode.jsencryptioncryptojs

Encrypt a file in node and decrypt in java using "AES/GCM/NoPadding". Basically AES/GCM/NoPadding equivalent in node.js


I have encrypt the file using node.js and decrypt in JAVA. Decryption is done in JAVA using "AES/GCM/Nopadding" algorithm and it is third party app hence I cannot change the JAVA code. I am encrypting the file in node.js using "aes-256-gcm" (not sure if it is equivalent to "AES/GCM/Nopadding") algorithm.

I have tried with crypto, node-forge npm module also tried setting cipher.setAutoPadding(false). But no luck. Could you please guide me where I am going wrong.

code in node.js

const
 algorithm = 'aes-256-gcm',
 randomKey = crypto.randomBytes( 32 ),
 randomIv = crypto.randomBytes( 16 );
const
 cipher = crypto.createCipheriv( algorithm, randomKey, randomIv ),
 input = fs.createReadStream( './imageTest.jpg.gz' ), //gzip image 
 output = fs.createWriteStream( './imageTest.jpg.gz.enc' );

input.pipe( cipher ).pipe( output );

code to decrypt in JAVA

byte[] decrypt(byte[] encrptedData, byte[] key, byte[] iv) {

    GCMParameterSpec ivSpec = new GCMParameterSpec(128, iv);
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), ivSpec);
    return cipher.doFinal(encryptedData);
}

When decrypting the file I get the below error at cipher.doFinal(encryptedData) step

Caused by: javax.crypto.AEADBadTagException: Tag mismatch!
    at com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:571)
    at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1046)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:983)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:845)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)

so I need to know how to achieve an equivalent in node.js


Solution

  • Add this line into NodeJs after the decryption is finished to get the authentication tag.

    const tag = cipher.getAuthTag();
    

    Transmit this tag, too.

    And. in Java part, append it before dofinal

    cipher.update(textBytes);