Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.

Closed 3 years ago .

I have a method to decrypt data:

private byte[] decrypt(byte[] sessionKey, byte[] initialisationVector, byte[] associatedData, byte[] cipherText, byte[] tag) {
    Key secret = new SecretKeySpec(sessionKey, "AES");
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, secret,
                new GCMParameterSpec((GCM_AUTHENTICATION_TAG_SIZE) * Byte.SIZE, initialisationVector));
    cipher.updateAAD(associatedData);
    return cipher.doFinal(concatByteArrays(cipherText, tag));

concatByteArrays is a simple method with Bytebuffer.allocate.put methods. UPD: input -

    byte[] TEST_AES_KEY = new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    int INITIALISATION_VECTOR_LENGTH = 12;
    int GCM_AUTHENTICATION_TAG_SIZE = 16;
    byte[] initialisationVector = Arrays.copyOfRange(receivedPacket, 0, INITIALISATION_VECTOR_LENGTH - 1);
    byte[] tag = Arrays.copyOfRange(receivedPacket, INITIALISATION_VECTOR_LENGTH, INITIALISATION_VECTOR_LENGTH + GCM_AUTHENTICATION_TAG_SIZE - 1);
    byte[] associatedData = Arrays.copyOfRange(receivedPacket, INITIALISATION_VECTOR_LENGTH + GCM_AUTHENTICATION_TAG_SIZE, receivedPacket.length - 1);
    byte[] cipherText = new byte[]{};
byte[] plainText = decrypt(key, initialisationVector, associatedData, cipherText, tag);

But get error:

javax.crypto.AEADBadTagException: Input too short - need tag
        at com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterM
ode.java:524)
        at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:104
        at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:985)
        at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
        at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
        at javax.crypto.Cipher.doFinal(Cipher.java:2164)

I can't understand how I can pass tag. I have a python code, which works:

decryptor = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend).decryptor()
decryptor.authenticate_additional_data(aad)
return decryptor.update(ciphertext) + decryptor.finalize()
                Possible duplicate of How come putting the GCM authentication tag at the end of a cipher stream require internal buffering during decryption?
– kelalaka
                Feb 17, 2020 at 13:15
                Thanks, I forgot about the tag at the end of cipherText. I added the tag to the cipherText but still get the same error
– Valeriy K.
                Feb 17, 2020 at 13:41
                No, kelalaka got it right, you either post an answer or you remove the question entirely. What yo don't do is to adjust the code in your question. Such off-by-one errrors are easy to make and maybe somebody else can learn from it.
– Maarten Bodewes
                Feb 17, 2020 at 14:50

Stupid mistake. I forgot that in arrays.copyof last parameter is exclusive and got wrong byte arrays from receivedPacket.

    byte[] initialisationVector = Arrays.copyOfRange(receivedPacket, 0, INITIALISATION_VECTOR_LENGTH);
    byte[] tag = Arrays.copyOfRange(receivedPacket, INITIALISATION_VECTOR_LENGTH, INITIALISATION_VECTOR_LENGTH + GCM_AUTHENTICATION_TAG_SIZE);
    byte[] associatedData = Arrays.copyOfRange(receivedPacket, INITIALISATION_VECTOR_LENGTH + GCM_AUTHENTICATION_TAG_SIZE, receivedPacket.length);
                You need to change the code for initializationVector, tag, linkedData in the original code from the question to the code from this answer. Aren't this clear?
– Valeriy K.
                Jan 4 at 8:38