1

I'm trying to decrypt a 50mb file in AES-GCM Mode (cipherinputstream) with JDK 1.11.0.6 and it takes 9 min while the same in CTR Mode mode takes 10s, am i missing anything here? Encryption in both CTR and GCM Mode takes around 600ms only

I've seen earlier post, Java 9: AES-GCM performance

I've tried with JDK 1.8,1.9,1.11.0.6 and even 1.13.

Surprisingly, JDK 1.9 takes 3 mins and all others takes around 9-10mins which is definitely not acceptable on comparing with the 10s taken in CTR Mode.

Same Code with Bouncy Castle Provider decrypts in 700ms. Difference between BC implementation and Native Java Implementation is so huge?

sample code,

public static void encryptfile() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IOException {
    InputStream fin = new FileInputStream("test.txt");
    OutputStream fout = new FileOutputStream("enc_test.txt");
    SecretKeySpec serverKey = new SecretKeySpec(HexConverterUtil.BASE16_DECODE("a4e97a4713841586ca639a416c636e3ef2a404efaf58b0a7768cd5758b1297a0"), "AES");
    GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * 8, HexConverterUtil.BASE16_DECODE("258f7d4c1c72bee0109bcbe5"));
    Cipher encryptCipher = Cipher.getInstance("AES/GCM/NoPadding");
    encryptCipher.init(Cipher.ENCRYPT_MODE, serverKey, gcmParameterSpec);
    fout = new CipherOutputStream(fout, encryptCipher);

    byte[] bytesBuffer = new byte[4096];
    int bytesRead = 0;

    while ((bytesRead = fin.read(bytesBuffer)) != -1) {
        fout.write(bytesBuffer, 0, bytesRead);
    }
    fin.close();
    fout.close();
}

public static void decryptfile() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IOException {
    InputStream fin = new FileInputStream("enc_test.txt");
    SecretKeySpec serverKey = new SecretKeySpec(HexConverterUtil.BASE16_DECODE("a4e97a4713841586ca639a416c636e3ef2a404efaf58b0a7768cd5758b1297a0"), "AES");
    GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * 8, HexConverterUtil.BASE16_DECODE("258f7d4c1c72bee0109bcbe5"));
    Cipher decryptCipher = Cipher.getInstance("AES/GCM/NoPadding");
    decryptCipher.init(Cipher.DECRYPT_MODE, serverKey, gcmParameterSpec);
    fin = new CipherInputStream(fin, decryptCipher);

    OutputStream fout = new BufferedOutputStream(new FileOutputStream("dec_test.mp3"));

    byte[] bytesBuffer = new byte[4096];
    int bytesRead = 0;

    while ((bytesRead = fin.read(bytesBuffer)) != -1) {
        fout.write(bytesBuffer, 0, bytesRead);
    }
    fin.close();
    fout.close();
}
  • This question will be better if you post your codes and measuring method, etc. How one can reproduce your case? – kelalaka Jan 22 '20 at 14:26
  • Added the sample code which i used to encrypt and decrypt a file in AES-GCM – vigneshwaran Jan 22 '20 at 15:11
  • 2
    [properbly this bug](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8201633) – Ebbe M. Pedersen Jan 22 '20 at 16:01
  • It's rather stupid that they didn't allow decryption before tag verification, which is why things like these fail. They should never have put the tag into the ciphertext in the first place. I agree with Ebbe, it's probably that bug. – Maarten Bodewes Jan 22 '20 at 22:35
  • the bug is supposed to be fixed in java 13 and backported to 11 and 12. But i get this problem in 11,12 and 13 as well. – vigneshwaran Jan 24 '20 at 09:20
  • Hmm, could you try with a buffer and `Cipher#update` / `#doFinal` and without the `CipherOutputStream`? You could also try mapping files and use `ByteBuffer`s, I don't know if that might be faster. Personally I don't like much about the `CipherIn/OutputStream` implementations so far. By the way, I'd use buffers of 1 MiB or so. I mean, who cares... – Maarten Bodewes Jan 24 '20 at 19:28
  • Even without AES-NI if shouldn't take minutes anyway, something is missing here. Indeed - couldn't you do as pure ByteBuffer operation? (without CipherStream) – gusto2 Jan 27 '20 at 16:10

0 Answers0