Current File : //opt/RZphp74/includes/Crypt/HMAC2.php |
<?php
/**
* Implementation of the Hashed Message Authentication Code algorithm with
* support for a wide range of hashing algorithms available using either of
* the "hash" or "mhash" extensions, or the native md5() and sha1() functions.
*
* PHP version 5
*
* LICENSE:
*
* Copyright (c) 2005-2007, Pádraic Brady <padraic.brady@yahoo.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category Encryption
* @package Crypt_HMAC2
* @author Pádraic Brady <padraic.brady@yahoo.com>
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version $Id: HMAC2.php 295302 2010-02-21 13:26:16Z clockwerx $
* @link http://
*/
/**
* Crypt_HMAC2 class
*
* Example usage:
* $key = str_repeat("\xaa", 20); // insecure key only for example
* $data = "Hello World!";
* $hmac = new Crypt_HMAC2($key, 'SHA256');
* $hmacHash = $hmac->hash($data);
*
* Supported hashing algorithms are limited by your PHP version access
* to the hash, mhash extensions and supported native functions like
* md5() and sha1().
*
* To obtain raw binary output, set the optional second parameter of
* Crypt_HMAC2::hash() to Crypt_HMAC2::BINARY.
*
* $hmacRawHash = $hmac->hash($data, Crypt_HMAC2::BINARY);
*
* @category Encryption
* @package Crypt_HMAC2
* @author Pádraic Brady <padraic.brady@yahoo.com>
* @copyright 2005-2007 Pádraic Brady
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://
* @version @package_version@
* @access public
*/
class Crypt_HMAC2
{
/**
* The key to use for the hash
*
* @var string
*/
protected $_key = null;
/**
* pack() format to be used for current hashing method
*
* @var string
*/
protected $_packFormat = null;
/**
* Hashing algorithm; can be the md5/sha1 functions or any algorithm name
* listed in the output of PHP 5.1.2+ hash_algos().
*
* @var string
*/
protected $_hashAlgorithm = 'md5';
/**
* Supported direct hashing functions in PHP
*
* @var array
*/
protected $_supportedHashNativeFunctions = array(
'md5',
'sha1',
);
/**
* List of hash pack formats for each hashing algorithm supported.
* Only required when hash or mhash are not available, and we are
* using either md5() or sha1().
*
* @var array
*/
protected $_hashPackFormats = array(
'md5' => 'H32',
'sha1' => 'H40'
);
/**
* List of algorithms supported my mhash()
*
* @var array
*/
protected $_supportedMhashAlgorithms = array('adler32',' crc32', 'crc32b', 'gost',
'haval128', 'haval160', 'haval192', 'haval256', 'md4', 'md5', 'ripemd160',
'sha1', 'sha256', 'tiger', 'tiger128', 'tiger160');
/**
* Constants representing the output mode of the hash algorithm
*/
const STRING = 'string';
const BINARY = 'binary';
/**
* Constructor; optionally set Key and Hash at this point
*
* @param string $key
* @param string $hash
*/
public function __construct($key = null, $hash = null)
{
if (!is_null($key)) {
$this->setKey($key);
}
if (!is_null($hash)) {
$this->setHashAlgorithm($hash);
}
}
/**
* Set the key to use when hashing
*
* @param string $key
* @return Crypt_HMAC2
*/
public function setKey($key)
{
if (!isset($key) || empty($key)) {
require_once 'Crypt/HMAC2/Exception.php';
throw new Crypt_HMAC2_Exception('provided key is null or empty');
}
$this->_key = $key;
return $this;
}
/**
* Getter to return the currently set key
*
* @return string
*/
public function getKey()
{
if (is_null($this->_key)) {
require_once 'Crypt/HMAC2/Exception.php';
throw new Crypt_HMAC2_Exception('key has not yet been set');
}
return $this->_key;
}
/**
* Setter for the hash method. Supports md5() and sha1() functions, and if
* available the hashing algorithms supported by the hash() PHP5 function or
* the mhash extension.
*
* Since they are so many varied HMAC methods in PHP these days this method
* does a lot of checking to figure out what's available and not.
*
* @param string $hash
* @return Crypt_HMAC2
*/
public function setHashAlgorithm($hash)
{
if (!isset($hash) || empty($hash)) {
require_once 'Crypt/HMAC2/Exception.php';
throw new Crypt_HMAC2_Exception('provided hash string is null or empty');
}
$hash = strtolower($hash);
$hashSupported = false;
if (function_exists('hash_algos') && in_array($hash, hash_algos())) {
$hashSupported = true;
}
if ($hashSupported === false && function_exists('mhash') && in_array($hash, $this->_supportedMhashAlgorithms)) {
$hashSupported = true;
}
if ($hashSupported === false && in_array($hash, $this->_supportedHashNativeFunctions) && in_array($hash, array_keys($this->_hashPackFormats))) {
$this->_packFormat = $this->_hashPackFormats[$hash];
$hashSupported = true;
}
if ($hashSupported === false) {
require_once 'Crypt/HMAC2/Exception.php';
throw new Crypt_HMAC2_Exception('hash algorithm provided is not supported on this PHP instance; please enable the hash or mhash extensions');
}
$this->_hashAlgorithm = $hash;
return $this;
}
/**
* Return the current hashing algorithm
*
* @return string
*/
public function getHashAlgorithm()
{
return $this->_hashAlgorithm;
}
/**
* Perform HMAC and return the keyed data
*
* @param string $data
* @param bool $internal Option to not use hash() functions for testing
* @return string
*/
public function hash($data, $output = self::STRING, $internal = false)
{
if (function_exists('hash_hmac') && $internal === false) {
if ($output == self::BINARY) {
return hash_hmac($this->getHashAlgorithm(), $data, $this->getKey(), 1);
}
return hash_hmac($this->getHashAlgorithm(), $data, $this->getKey());
}
if (function_exists('mhash') && $internal === false) {
if ($output == self::BINARY) {
return mhash($this->_getMhashDefinition($this->getHashAlgorithm()), $data, $this->getKey());
}
$bin = mhash($this->_getMhashDefinition($this->getHashAlgorithm()), $data, $this->getKey());
return bin2hex($bin);
}
// last ditch effort for MD5 and SHA1 only
$key = $this->getKey();
$hash = $this->getHashAlgorithm();
if (strlen($key) < 64) {
$key = str_pad($key, 64, chr(0));
} elseif (strlen($key) > 64) {
$key = pack($this->_packFormat, $this->_digest($hash, $key, $output));
}
$padInner = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
$padOuter = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
return $this->_digest($hash, $padOuter . pack($this->_packFormat, $this->_digest($hash, $padInner . $data, $output)), $output);
}
/**
* Method of working around the inability to use mhash constants; this
* will locate the Constant value of any support Hashing algorithm named
* in the string parameter.
*
* @param string $hashAlgorithm
* @return integer
*/
protected function _getMhashDefinition($hashAlgorithm)
{
for ($i = 0; $i <= mhash_count(); $i++) {
$types[mhash_get_hash_name($i)] = $i;
}
return $types[strtoupper($hashAlgorithm)];
}
/**
* Digest method when using native functions which allows the selection
* of raw binary output.
*
* @param string $hash
* @param string $key
* @param string $mode
* @return string
*/
protected function _digest($hash, $key, $mode)
{
if ($mode == self::BINARY) {
return $hash($key, true);
}
return $hash($key);
}
}