The Sun JCE implementation of GCM is hard coded to refuse to encode more than 2 Gb, through the function GaloisCounterMode.checkDataLength() that returns an error message : "SunJCE provider only supports input size up to 2147483647 byte" (the message sounds API generic, but the implementation shows the check is specifically for GCM and some other alg don't have that limitation).

It's documented than GCM has a plain text limit at 64 Gb, but could it be that some of the parameters used in that implementation justify the limit to 2 Gb instead ?
The Bouncy Castle implementation doesn't limit to this size, is this expected ?


2 Answers 2


Quoting the comment on the limit value:

    // In NIST SP 800-38D, GCM input size is limited to be no longer
    // than (2^36 - 32) bytes. Otherwise, the counter will wrap
    // around and lead to a leak of plaintext.
    // However, given the current GCM spec requirement that recovered
    // text can only be returned after successful tag verification,
    // we are bound by limiting the data size to the size limit of
    // java byte array, e.g. Integer.MAX_VALUE, since all data
    // can only be returned by the doFinal(...) call.
    private static final int MAX_BUF_SIZE = Integer.MAX_VALUE;

In other words, decrypting has to buffer the whole ciphertext (even if you pass to update in pieces) which it does in a Java byte array, and by the long established JVM spec a Java array can't exceed 2^31-1 elements (or available heap space, if less, but you can't generally determine that in advance). This is actually a problem only for decrypting, but they apparently added the check on encrypting so you can't encrypt data and then be unable to decrypt it and thus permanently lose all the data you considered valuable, which some users would consider undesirable. (Although you could work around it using BouncyCastle, which doesn't enforce the 800-36D restriction -- or OpenSSL, ditto, but less easy to use in Java.)

See previous
Encryption of big files in Java with AES/GCM


2147483647 is the larger value that fits a Java int. Since they use a int to keep track of how many byte were processed, they had to impose that limit...


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.