Skip to content

Instantly share code, notes, and snippets.

@cetver
Created November 17, 2014 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cetver/b914e56c1fb9ec98681c to your computer and use it in GitHub Desktop.
Save cetver/b914e56c1fb9ec98681c to your computer and use it in GitHub Desktop.
Yii2 security component with sha1 hmac algorythm
<?php
namespace common\components;
use yii\base\Security;
use yii\base\InvalidConfigException;
use yii\helpers\StringHelper;
/**
*
* Security provides a set of methods to handle common security-related tasks.
* Compatible with CSecurityManager from Yii 1.x (CSecurityManager.validationKey === Security.cookieValidationKey).
*
* In particular, Security supports the following features:
*
* - Encryption/decryption: [[encryptByKey()]], [[decryptByKey()]], [[encryptByPassword()]] and [[decryptByPassword()]]
* - Key derivation using standard algorithms: [[pbkdf2()]] and [[hkdf()]]
* - Data tampering prevention: [[hashData()]] and [[validateData()]]
* - Password validation: [[generatePasswordHash()]] and [[validatePassword()]]
*
* > Note: this class requires 'mcrypt' PHP extension. For the highest security level PHP version >= 5.5.0 is recommended.
*
*/
class MacHashSHA1 extends Security
{
/**
* Hash algorithm for message authentication.
*/
const MAC_HASH = 'sha1';
/**
* Prefixes data with a keyed hash value so that it can later be detected if it is tampered.
* There is no need to hash inputs or outputs of [[encryptByKey()]] or [[encryptByPassword()]]
* as those methods perform the task.
* @param string $data the data to be protected
* @param string $key the secret key to be used for generating hash. Should be a secure
* cryptographic key.
* @param boolean $rawHash whether the generated hash value is in raw binary format. If false, lowercase
* hex digits will be generated.
* @throws InvalidConfigException
* @return string the data prefixed with the keyed hash
* @see validateData()
* @see generateRandomKey()
* @see hkdf()
* @see pbkdf2()
*/
public function hashData($data, $key, $rawHash = false)
{
$hash = hash_hmac(self::MAC_HASH, $data, $key, $rawHash);
if (!$hash) {
throw new InvalidConfigException('Failed to generate HMAC with hash algorithm: ' . self::MAC_HASH);
}
return $hash . $data;
}
/**
* Validates if the given data is tampered.
* @param string $data the data to be validated. The data must be previously
* generated by [[hashData()]].
* @param string $key the secret key that was previously used to generate the hash for the data in [[hashData()]].
* function to see the supported hashing algorithms on your system. This must be the same
* as the value passed to [[hashData()]] when generating the hash for the data.
* @param boolean $rawHash this should take the same value as when you generate the data using [[hashData()]].
* It indicates whether the hash value in the data is in binary format. If false, it means the hash value consists
* of lowercase hex digits only.
* hex digits will be generated.
* @throws InvalidConfigException
* @return string the real data with the hash stripped off. False if the data is tampered.
* @see hashData()
*/
public function validateData($data, $key, $rawHash = false)
{
$test = @hash_hmac(self::MAC_HASH, '', '', $rawHash);
if (!$test) {
throw new InvalidConfigException('Failed to generate HMAC with hash algorithm: ' . self::MAC_HASH);
}
$hashLength = StringHelper::byteLength($test);
if (StringHelper::byteLength($data) >= $hashLength) {
$hash = StringHelper::byteSubstr($data, 0, $hashLength);
$pureData = StringHelper::byteSubstr($data, $hashLength, null);
$calculatedHash = hash_hmac(self::MAC_HASH, $pureData, $key, $rawHash);
if ($this->compareString($hash, $calculatedHash)) {
return $pureData;
}
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment