Skip to content

Instantly share code, notes, and snippets.

@MatthiasKunnen
Created August 18, 2017 09:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MatthiasKunnen/828a8d2d75bc0f40a8e8ae74724c0975 to your computer and use it in GitHub Desktop.
Save MatthiasKunnen/828a8d2d75bc0f40a8e8ae74724c0975 to your computer and use it in GitHub Desktop.
Wrapper for generating and verifying HMACs
class MessageAuthenticationHelper
{
const HMAC_TAG_NAME = 'tag';
/** @var string The hash algorithm used for generating a HMAC */
protected $hashAlgorithm = 'sha256';
/** @var string The secret HMAC key. */
protected $hmacKey;
/**
* Generate HMAC for the supplied data.
* @param string|string[] $data A single piece of data, or a
* collection of it, that will be used to create a tag for integrity checks.
* @return string Generated HMAC.
* @throws \Exception If no secret key was found.
*/
public function generateHMAC($data)
{
if ($this->hmacKey === null) {
throw new \Exception('HMAC secret key not found!');
}
if (is_array($data)) {
$stringData = '';
foreach ($data as $key => $value) {
$stringData .= $key . $value;
}
$data = $stringData;
}
return hash_hmac($this->hashAlgorithm, $data, $this->hmacKey);
}
/**
* Verify whether the *data* was altered using the HMAC for comparison. Make
* sure that the values in the *data* variable are in the same order that
* they were when creating the HMAC.
* @param string|string[] $data A single piece of data, or a
* collection of it, that will be checked for integrity.
* @param string $hmac The HMAC used to check the integrity of the data.
* @return bool True when the data has not been tampered with, false
* otherwise.
*/
public function verifyHMAC($data, $hmac)
{
return self::generateHMAC($data) === $hmac;
}
/**
* Generates the url encoded parameters with a parameter containing the
* HMAC used in integrity checks.
* @param string[] $data Collection containing the parameters' key value
* pairs. Cannot contain a key equal to HMAC_TAG_NAME.
* @return string Url encoded parameters for message authentication
* purposes.
* @throws \Exception
*/
public function generateHmacUrlParameters($data)
{
if (array_key_exists(self::HMAC_TAG_NAME, $data)) {
throw new \Exception(sprintf('Array supplied to HMAC url'
. 'generation method already contains a "%s" key.',
self::HMAC_TAG_NAME));
}
$data[self::HMAC_TAG_NAME] = $this->generateHMAC($data);
return http_build_query($data);
}
/**
* Verifies the integrity of the parameters that have been provided.
* @param string[] $parameters Collection of key value pairs that need to
* be checked for integrity.
* @return bool True if the parameters have not been tampered with, false
* otherwise.
*/
public function verifyHmacUrlParameters($parameters)
{
if (!array_key_exists(self::HMAC_TAG_NAME, $parameters)) {
return false;
}
$cleaned = $parameters;
unset($cleaned[self::HMAC_TAG_NAME]);
return self::verifyHMAC($cleaned, $parameters[self::HMAC_TAG_NAME]);
}
/**
* @return string
*/
public function getHashAlgorithm()
{
return $this->hashAlgorithm;
}
/**
* @param string $hashAlgorithm
* @return MessageAuthenticationHelper
*/
public function setHashAlgorithm($hashAlgorithm)
{
$this->hashAlgorithm = $hashAlgorithm;
return $this;
}
/**
* @return string
*/
public function getHmacKey()
{
return $this->hmacKey;
}
/**
* @param string $hmacKey
* @return MessageAuthenticationHelper
*/
public function setHmacKey($hmacKey)
{
$this->hmacKey = $hmacKey;
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment