I am looking for an easy way calculate an HMAC over the ciphertext in Java (encrypt-then-MAC, including the IV and algorithm parameters) using InputStream/OutputStreams.
Failed attempt: I first tried inheriting from CipherOutputStream, but they do not allow retrieving the ciphertext programatically after after it has been written -- leading me to the conclusion that using CipherOutputStream only MAC-then-encrypt can be implemented. Code here: http://pastebin.com/armvDN3N
Successful attempt: I then used the OpenJDK7 source code of CipherOutputStream as a basis to implement a CipherHmacOutputStream class, that updates the Hmac whenever write() is called (mac.update()) and appends it to the stream when close is called. Code here: http://pastebin.com/fF8WFBpA
The problem now is when I try to write a matching CipherHmacInputStream, there is no obvious way to tell when the HMAC begins, because there is no way to tell when the stream ends. The available() method only returns the "new" decrypted bytes in the buffer. As a result, the decryption (cipher.update()) might wrongfully try to decrypt the HMAC. I already invested a bit of time in this, but there must be an easier way to do stream-based encryption/decryption with HMACs. GCM/EAX are the obvious answers, but I want to leave the algorithms/modes configurable, and also offer message authentication if GCM/EAX is not used.
Do you have any ideas? Are there any standard ways to do this?