isAllowedForHmac()) { throw new \LogicException('The ' . __METHOD__ . ' function does not allow "' . $algo->value . '".', 1763812644); } $secret = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . $additionalSecret; return hash_hmac($algo->value, $input, $secret); } /** * Appends a hash (HMAC) to a given string and additional secret and returns the result * * @param non-empty-string $additionalSecret * * @return non-empty-string */ public function appendHmac(string $string, string $additionalSecret, HashAlgo $algo = HashAlgo::SHA1): string { return $string . $this->hmac($string, $additionalSecret, $algo); } /** * Returns, if a string $string and $additionalSecret matches the HMAC given by $hash. * * @param non-empty-string $additionalSecret */ public function validateHmac(string $string, string $additionalSecret, string $hmac, HashAlgo $algo = HashAlgo::SHA1): bool { return hash_equals($this->hmac($string, $additionalSecret, $algo), $hmac); } /** * Tests if the last 40 characters of a given string $string and $additionalSecret matches the HMAC of * the rest of the string and, if true, returns the string without the HMAC. In case of an invalid HMAC string * an exception is thrown. * * @param non-empty-string $string * @param non-empty-string $additionalSecret */ public function validateAndStripHmac(string $string, string $additionalSecret, HashAlgo $algo = HashAlgo::SHA1): string { $hashLength = $algo->length(); if (strlen($string) < $hashLength) { throw new InvalidHashStringException( sprintf( 'A hashed string must contain at least %d characters, the given string was only %d characters long.', $hashLength, strlen($string) ), 1704454152 ); } $stringWithoutHmac = substr($string, 0, -$hashLength); if ($this->validateHmac($stringWithoutHmac, $additionalSecret, substr($string, -$hashLength), $algo) !== true) { throw new InvalidHashStringException('The given string was not appended with a valid HMAC.', 1704454157); } return $stringWithoutHmac; } }