AES GCM symmetric encryption of data at rest in c#, ciphertext much longer than plaintext I've written encryption/decryption routines using AES GCM. Code can be found here.

I recently realized that the cipher text is longer than I believe it should be. It should add the tag and IV onto the encrypted plaintext, but the result is still longer than it should be. 

Here is the portion of the code doing the encrypting



    using (MemoryStream ms = new MemoryStream())
            {
                using (IAuthenticatedCryptoTransform encryptor = aes.CreateAuthenticatedEncryptor())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))

                    {   
                        // Write through and retrieve encrypted data.
                        cs.Write(message, 0, message.Length);
                        cs.FlushFinalBlock();
                        byte[] cipherText = ms.ToArray();                   

                        // Retrieve tag and create array to hold encrypted data.
                        byte[] authenticationTag = encryptor.GetTag();      
                        byte[] encrypted = new byte[cipherText.Length + aes.IV.Length + authenticationTag.Length];

                        // Set needed data in byte array.
                        aes.IV.CopyTo(encrypted, 0);                       
                        authenticationTag.CopyTo(encrypted, IV_LENGTH);
                        cipherText.CopyTo(encrypted, IV_LENGTH + TAG_LENGTH);

                        // Store encrypted value in base 64.
                        return Convert.ToBase64String(encrypted);
                     }
                 }
             }




Here are two examples of the encryption:

plaintext: example

ciphertext: XtmTBIqKxKdYKWH2zXRUp8jN6etGNUiTyffAFZYV3KB2WVU=

plaintext: much longer example, blah blah blah blah blah

ciphertext: H17hnG4CSmZQ0UeEcY6wirtjW1il+dw7JHqXwWm908Tvb8/+q0E1HerN0chbuUbhL0jLOs8HIpp7ypQQ/ LTacnWW22CyiwAuiA==

The IV is 12 bytes. And I believe the authentication tag is 16 bytes. Why is the cipher text coming out so much longer than expected and how should I fix this issue?
Thank you.
If you go through the math, it appears that exactly the expected amount of ciphertext expansion is happening.  Here's what's happening:


The GCM takes the plaintext as a byte string of size N, and generates a ciphertext which is a byte string of size N+28, where 12 of the 28 is the nonce, and the other 16 is the authentication tag.
Then, that octet string undergoes a base-64 encoding, which converts 3 bytes into 4 printable characters; this gives an average ciphertext expansion of a factor of 4/3.


In the first case, you had a plaintext of 7 bytes; after encryption, that gives you a ciphertext of 35 bytes; the base-64 encoding of these 35 bytes would be expected to be 47 bytes long, which is exactly what you see.

In the second case, you had a plaintext of 46 bytes (assuming there's a trailing space to the string you gave); after encryption, that gives you a ciphertext of 74 bytes; the base-64 encoding is then 99 bytes, which is exactly what you see.

Now, you ask how you should fix this issue.  Well, the transform is working as designed; what is the issue?  If the issue was that you were concerned that something wasn't working properly, well, everything appears to be correct.  If the issue was that the ciphertext was too long for your application, well, you'd need to consider how to trim it.  Here are some easy ways:


Do you really need the output to be printable?  Well, I see you put the 'database' tag on the question; are you encrypting a database field?  If so, can the database store arbitrary bytes, or is it restricted only to printable strings?  If it can store arbitrary bytes, then you can get rid of a good part of the overhead simply by not base-64 encoding the text.  If you do, well, if you're desperate, there are some more aggressive encoding methods (which use more characters in their outputs); going to one of those would save you some small amount.