2
$\begingroup$

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:

  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?

  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?

  3. Should I use Bouncy Castle instead of using default Java implementation?

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

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

$\endgroup$
2
  • $\begingroup$ You appear to be using blockSize as the size of the IV added to and later removed from the ciphertext, but your generateIV() call doesn't use it. Moreover, unlike several other modes, the IV for GCM is not fixed at the size of the cipher block; in fact AES' blocksize is 16 octets but the preferred GCM IV size is 12 octets (although it does handle 16). $\endgroup$ Oct 5, 2016 at 1:17
  • $\begingroup$ Note to other users: code specific questions are better asked at StackOverflow. These questions are mostly about the cryptography itself rather than API usage so it is on topic here, but generally try and avoid basing questions on code. Just showing some code fragments as demonstration below the questions is probably a better idea than inserting a large block of code on top of the question as done here, as users will probably try and close the question if you do. $\endgroup$
    – Maarten Bodewes
    Mar 21, 2019 at 12:44

1 Answer 1

3
$\begingroup$

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.

$\endgroup$
1
  • 2
    $\begingroup$ And I originally implemented the NIST and HKDF algorithms for Bouncy, so I'm pretty sure they are in there :P $\endgroup$
    – Maarten Bodewes
    Oct 3, 2016 at 23:04

Your Answer

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

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