AES-GCM encryption and decryption doubts I'm using AES-GCM mode in my project and I have some doubts.

public String encrypt(String plainText, String authenticationTag) throws GeneralSecurityException, IOException {
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
        final int blockSize = cipher.getBlockSize();
        SecretKey secretKey = readKeyFile(...);
        byte[] plainTextByte = plainText.trim().getBytes(Charset.forName("UTF-8"));
        byte[] ivBytes = generateIV();
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(GCM_TAG_LENGTH, ivBytes));
        cipher.updateAAD(authenticationTag.getBytes(Charset.forName("UTF-8")));
        byte[] encryptedMessage = cipher.doFinal(plainTextByte);
        byte iv_and_encryptedMessage[] = concatIvAndCipher(ivBytes, encryptedMessage, blockSize);
        Base64.Encoder encoder = Base64.getEncoder().withoutPadding();
        String iv_and_encryptedText = encoder.encodeToString(iv_and_encryptedMessage);
        return iv_and_encryptedText;
    }

    public String decrypt(String iv_and_encryptedTextBase64, String authenticationTag)
            throws GeneralSecurityException, IOException {
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
        final int blockSize = cipher.getBlockSize();
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] iv_and_encryptedMessage = decoder.decode(iv_and_encryptedTextBase64.trim());
        byte[] ivBytes = extractIvFrom(iv_and_encryptedMessage, blockSize);
        byte[] encryptedTextBytes = extractEncryptedMessageFrom(iv_and_encryptedMessage, blockSize);
        SecretKey secretKey = readKeyFile(...);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(GCM_TAG_LENGTH, ivBytes));
        cipher.updateAAD(authenticationTag.getBytes(Charset.forName("UTF-8")));
        byte[] decryptedByte = cipher.doFinal(encryptedTextBytes);
        String decryptedMessage = new String(decryptedByte, Charset.forName("UTF-8"));
        return decryptedMessage;
    }


Questions:


I'm using a GUID as authentication tag which is binding to a user to whom the sensitive information belongs. The encrypted text and tag is stored in separate databases at separate locations. Is this OK?
From what I've read AES-GCM takes in (plain text, IV, key, associated data) and outputs (cipher text, authentication tag). Are associated data and authentication tag the same thing, because my implementation of encrypt and decrypt work when I pass same value in cipher.updateAAD(...)? How to obtain the authentication tag after encrypting?
Should I use Bouncy Castle instead of using default Java implementation?
If the data to encrypt is 16 bytes, when should I generate a new DEK for enc/dec?
One master KEK for all DEK's? For encrypting DEK's should I use same AES implementation? If not, then what to use?
1) I'm using a GUID as authentication tag which is binding to a user to whom the sensitive information belongs. The encrypted text and tag is stored in separate databases at separate locations. Is this ok?


You're not using the GUID as authentication tag, you're using it as additional authenticated data, which is OK, especially since you've already shared a key. The authentication tag is - when using the somewhat hacked Java API - output at the end of the ciphertext.


  2) From what I've read AES-GCM takes in (plain text, IV, key, associated data) and outputs (cipher text, authentication tag). Are associated data and authentication tag the same thing, because my implementation of encrypt and decrypt work when I pass same value in cipher.updateAAD(...)? How to obtain the authentication tag after encrypting?


No, see above. If you want to get the authentication tag you may want to strip it off the end of the ciphertext.


  3) Should I use BouncyCastle instead of using default Java implementation.


Not unless you want to forgo AES-NI and GCM optimizations. I'd stay away from Bouncy Castle for implementations already present in the API provided by OpenJDK / Oracle runtimes.'


  4) If the data to encrypt is 16 bytes, when should I generate a new DEK for enc/dec.


See the NIST GCM specifications; in general it depends on the authentication tag size, so there multiple answers possible.

The constant value of GCM_TAG_LENGTH is not displayed in the code of the question though, so it is unclear what the authentication tag size is in your particular case.

In the comments an authentication tag size of 128 bits was mentioned. The NIST GCM specifications are not entirely clear on that, so I asked for the sizes in this question which was answered a whole lot later.


  5) One master KEK for all DEK's? For encrypting DEK's should I use same AES implementation? If not, then what to use?


That depends on the protocol and, in the end, the use cases and threat model. But in general I'd use a KDF such as HKDF to derive keys rather than to wrap (encrypt) them. Now for that you might want to use Bouncy Castle, because there aren't any good KDF's implemented in Java itself.