ByteArrayGuard class randomly outputs "ERROR: MAC did not verify!" messages to the error console. This only occurs when client side viewstate encryption is enabled and that multiple clients are running against the server.
ByteArrayGuard's instances of javax.crypto.Mac are used in a way that is not thread-safe.
ByteArrayGuard creates 2 instances of the Mac object and recycles them through the whole application lifecycle. During encryption and decryption, Macs get updated and calculated. If multiple threads run any of these 2 operations simultaneously on a (shared) Mac instance, the calculated Mac can be corrupted.
[Steps to reproduce]
1)Enable client viewstate encryption:
-Enable viewstate encryption (http://docs.oracle.com/cd/E19575-01/819-3669/bnaxo/index.html)
-Set state saving method to "client"
2)Run an intensive multi-user load test (e.g. using JMeter/LoadRunner). Each user must perform actions leading to:
-Make the client store the viewstate encrypted by the server
-Make the server process the encrypted viewstate stored by the client
In my case, the error message appeared randomly, for about 5% of requests.
Mac instanciation and initialization can be moved to the encrypt/decrypt procedure. Various threads will therefore not share Mac instances. I implemented this solution and tested it. It does not lead to notable performance drawbacks. See attachments.