[Esapi-dev] ESAPI Java and Authenticated encryption implementation

Philippe Arteau philippe.arteau at gmail.com
Wed Aug 21 21:41:55 UTC 2013

The authenticated encryption implementation in ESAPI 2 seems to have logic

Expected use of MAC on CipherText (has seen in
        CipherText ct = ESAPI.encryptor().encrypt(new

        //Serialize the ciphertext...
        byte[] serializedCt = ct.asPortableSerializedByteArray();

        CipherText ctReload =
        PlainText pt = ESAPI.encryptor().decrypt(sk,ctReload);

The decrypt() function does a validation prior the decryption:
      boolean valid = CryptoHelper.isCipherTextMACvalid(key, ciphertext);
      if (!valid)
        throw new EncryptionException("Decryption failed; see logs for
details.", "Decryption failed because MAC invalid for " + ciphertext);
      plaintext = handleDecryption(key, ciphertext);

The problem is that the MAC validation can be bypassed under certain

*Condition #1*: if the Ciphertext is tampered to contains a MAC that is null

  public boolean validateMAC(SecretKey authKey)
    boolean usesMAC = ESAPI.securityConfiguration().useMACforCipherText();

    if ((usesMAC) && (macComputed()))
      byte[] mac = computeMAC(authKey);
      assert (mac.length == this.separate_mac_.length) : "MACs are of
differnt lengths. Should both be the same.";
      return CryptoHelper.arrayCompare(mac, this.separate_mac_);
    }if (!usesMAC) {
      return true;
    logger.warning(Logger.SECURITY_FAILURE, "Cannot validate MAC as it was
never computed and stored. Decryption result may be garbage even when
decryption succeeds.");

    return true;

  private boolean macComputed()
    return this.separate_mac_ != null;

Disabling the MAC validation allow different kinds of attacks that involve
altering the ciphertext. (Oracle Padding Attack, IV manipulation, Direct
block manipulation)

*Condition #2*: if the cipherSpec is tampered to use a different mode that
is not part of combinedCipherModes

public static boolean isCombinedCipherMode(String cipherMode)
    assert (cipherMode != null) : "Cipher mode may not be null";
    assert (!cipherMode.equals("")) : "Cipher mode may not be empty string";
    List combinedCipherModes =

    return combinedCipherModes.contains(cipherMode);
public static boolean isMACRequired(CipherText ct)
    boolean preferredCipherMode = isCombinedCipherMode(ct.getCipherMode());

    boolean wantsMAC = ESAPI.securityConfiguration().useMACforCipherText();

    return (!preferredCipherMode) && (wantsMAC);

The design to compute the mac for only a portion of the message is kind of
broken. The mac should cover all parameters serialized. Authenticated
encryption implementation should not use logic that support optional MAC.

A proof of concept of the attack described previously is attached.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.owasp.org/pipermail/esapi-dev/attachments/20130821/48f4d767/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: esapi-mac.zip
Type: application/zip
Size: 2660 bytes
Desc: not available
URL: <http://lists.owasp.org/pipermail/esapi-dev/attachments/20130821/48f4d767/attachment.zip>

More information about the Esapi-dev mailing list