public function decryptAndVerify($ciphertext, $tag, $cek, $additional, $iv) { $params = self::$alg_params[$this->getAlg()]; if (strlen($cek) != $this->getCEKSize() / 8) { throw new CryptException('Incorrect key length'); } $iv = Util::base64url_decode($iv); if (strlen($iv) != $this->getIVSize() / 8) { throw new CryptException('Incorrect IV length'); } list($mac_key, $enc_key) = str_split($cek, (int) (strlen($cek) / 2)); $al = Util::packInt64(strlen($additional) * 8); $e = Util::base64url_decode($ciphertext); $m = hash_hmac($params['hash'], $additional . $iv . $e . $al, $mac_key, true); $t = substr($m, 0, $params['tag']); if (!Util::secure_compare(Util::base64url_decode($tag), $t)) { throw new CryptException('Authentication tag does not match'); } $plaintext = openssl_decrypt($e, $params['cipher'], $enc_key, OPENSSL_RAW_DATA, $iv); return $plaintext; }