Stating "AES" is not enough to specify some encryption. AES is a block cipher, not a cipher. It's used per some operating mode. Among these
- ECB without padding has the desired property that one can concatenate ciphertext fragments without decompression artifact, but is unsafe, and works only if the plaintext is an exact multiple of the AES block size (16 bytes).
- CBC and CFB with IV prepended as ciphertext (which is usual) would do precisely what's reported: "when I decrypt 20 (concatenated ciphertext fragments) together it sounds like the original but with some clinky noise" because the IV (and perhaps some padding in the previous fragment) is misinterpreted as data, and inserts an error;
- CTR or OFB would not recover from the error, and thus only the first 1/20 of the audio would be intelligible.
- GCM or other authenticated mode would not output anything.
Is it possible using AES or another method to call my decrypt function on the concatenated 20 messages as one message and get the concatenated decrypted results?
Yes. One needs to take come precautions w.r.t. padding, but if the existing encryption procedure splits the data on some multiple of 16 bytes, there's nothing to change on encryption. Just remove from the output the extra data that corresponds to the inserted IV, and perhaps padding. That's merely 19 memory copy, over 19/20 of the data. It might save time, or not, depending on off-topic considerations.
For padding, the plaintext fragments should be aligned on multiples of 16 bytes (except for the last).
Encryption can be with padding (as most libraries do), but then one should either
- Remove the last 16 bytes of each ciphertext fragment except the last before joining the ciphertext fragments; and remove the 16 bytes of IV at each of the 19 fragment frontiers in the output of decryption.
- Remove the 16 bytes of data the padding generated (thus removing 32 bytes at each of the 19 fragment frontiers: 16 for padding of the previous fragment, and 16 for IV of the next one).
Alternatively, one can encrypt without padding, and manually pad the last plaintext fragment with zeroes, which for most compressed audio gets removed by the player, and for some uncompressed audio is silence.