PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/phpmyfaq/inc/libs/phpseclib/Crypt/Hash.php

http://github.com/thorsten/phpMyFAQ
PHP | 284 lines | 122 code | 18 blank | 144 comment | 11 complexity | afef9bf65270d7e78aaa6a8e55e94c20 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
  5. *
  6. * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports md5, md5-96, sha1, and
  7. * sha1-96. If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as
  8. * as opposed to the hash. If no valid algorithm is provided, sha1 will be used.
  9. *
  10. * PHP versions 4 and 5
  11. *
  12. * {@internal The variable names are the same as those in
  13. * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
  14. *
  15. * Here's a short example of how to use this library:
  16. * <code>
  17. * <?php
  18. * include('Crypt/Hash.php');
  19. *
  20. * $hash = new Crypt_Hash('sha1');
  21. *
  22. * $hash->setKey('abcdefg');
  23. *
  24. * echo base64_encode($hash->hash('abcdefg'));
  25. * ?>
  26. * </code>
  27. *
  28. * LICENSE: This library is free software; you can redistribute it and/or
  29. * modify it under the terms of the GNU Lesser General Public
  30. * License as published by the Free Software Foundation; either
  31. * version 2.1 of the License, or (at your option) any later version.
  32. *
  33. * This library is distributed in the hope that it will be useful,
  34. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  36. * Lesser General Public License for more details.
  37. *
  38. * You should have received a copy of the GNU Lesser General Public
  39. * License along with this library; if not, write to the Free Software
  40. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  41. * MA 02111-1307 USA
  42. *
  43. * @category Crypt
  44. * @package Crypt_Hash
  45. * @author Jim Wigginton <terrafrost@php.net>
  46. * @copyright MMVII Jim Wigginton
  47. * @license http://www.gnu.org/licenses/lgpl.txt
  48. * @version $Id: Hash.php,v 1.3 2009/05/27 16:15:23 terrafrost Exp $
  49. * @link http://phpseclib.sourceforge.net
  50. */
  51. /**#@+
  52. * @access private
  53. * @see Crypt_Hash::Crypt_Hash()
  54. */
  55. /**
  56. * Toggles the internal implementation
  57. */
  58. define('CRYPT_HASH_MODE_INTERNAL', 1);
  59. /**
  60. * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
  61. */
  62. define('CRYPT_HASH_MODE_MHASH', 2);
  63. /**
  64. * Toggles the hash() implementation, which works on PHP 5.1.2+.
  65. */
  66. define('CRYPT_HASH_MODE_HASH', 3);
  67. /**#@-*/
  68. /**
  69. * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
  70. *
  71. * @author Jim Wigginton <terrafrost@php.net>
  72. * @version 0.1.0
  73. * @access public
  74. * @package Crypt_Hash
  75. */
  76. class Crypt_Hash {
  77. /**
  78. * Byte-length of compression blocks / key (Internal HMAC)
  79. *
  80. * @see Crypt_Hash::setAlgorithm()
  81. * @var Integer
  82. * @access private
  83. */
  84. var $b;
  85. /**
  86. * Byte-length of hash output (Internal HMAC)
  87. *
  88. * @see Crypt_Hash::setHash()
  89. * @var Integer
  90. * @access private
  91. */
  92. var $l;
  93. /**
  94. * Hash Algorithm
  95. *
  96. * @see Crypt_Hash::setHash()
  97. * @var String
  98. * @access private
  99. */
  100. var $hash;
  101. /**
  102. * Key
  103. *
  104. * @see Crypt_Hash::setKey()
  105. * @var String
  106. * @access private
  107. */
  108. var $key = '';
  109. /**
  110. * Outer XOR (Internal HMAC)
  111. *
  112. * @see Crypt_Hash::setKey()
  113. * @var String
  114. * @access private
  115. */
  116. var $opad;
  117. /**
  118. * Inner XOR (Internal HMAC)
  119. *
  120. * @see Crypt_Hash::setKey()
  121. * @var String
  122. * @access private
  123. */
  124. var $ipad;
  125. /**
  126. * Default Constructor.
  127. *
  128. * @param optional String $hash
  129. * @return Crypt_Hash
  130. * @access public
  131. */
  132. function Crypt_Hash($hash = 'sha1')
  133. {
  134. if ( !defined('CRYPT_HASH_MODE') ) {
  135. switch (true) {
  136. case extension_loaded('hash'):
  137. define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
  138. break;
  139. case extension_loaded('mhash'):
  140. define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
  141. break;
  142. default:
  143. define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
  144. }
  145. }
  146. $this->setHash($hash);
  147. }
  148. /**
  149. * Sets the key for HMACs
  150. *
  151. * Keys can be of any length.
  152. *
  153. * @access public
  154. * @param String $key
  155. */
  156. function setKey($key)
  157. {
  158. $this->key = $key;
  159. }
  160. /**
  161. * Sets the hash function.
  162. *
  163. * @access public
  164. * @param String $hash
  165. */
  166. function setHash($hash)
  167. {
  168. switch ($hash) {
  169. case 'md5-96':
  170. case 'sha1-96':
  171. $this->l = 12; // 96 / 8 = 12
  172. break;
  173. case 'md5':
  174. $this->l = 16;
  175. break;
  176. case 'sha1':
  177. $this->l = 20;
  178. }
  179. switch ( CRYPT_HASH_MODE ) {
  180. case CRYPT_HASH_MODE_MHASH:
  181. switch ($hash) {
  182. case 'md5':
  183. case 'md5-96':
  184. $this->hash = MHASH_MD5;
  185. break;
  186. case 'sha1':
  187. case 'sha1-96':
  188. default:
  189. $this->hash = MHASH_SHA1;
  190. }
  191. return;
  192. case CRYPT_HASH_MODE_HASH:
  193. switch ($hash) {
  194. case 'md5':
  195. case 'md5-96':
  196. $this->hash = 'md5';
  197. return;
  198. case 'sha1':
  199. case 'sha1-96':
  200. default:
  201. $this->hash = 'sha1';
  202. }
  203. return;
  204. }
  205. switch ($hash) {
  206. case 'md5':
  207. case 'md5-96':
  208. $this->b = 64;
  209. $this->hash = 'md5';
  210. break;
  211. case 'sha1':
  212. case 'sha1-96':
  213. default:
  214. $this->b = 64;
  215. $this->hash = 'sha1';
  216. }
  217. $this->ipad = str_repeat(chr(0x36), $this->b);
  218. $this->opad = str_repeat(chr(0x5C), $this->b);
  219. }
  220. /**
  221. * Compute the HMAC.
  222. *
  223. * @access public
  224. * @param String $text
  225. */
  226. function hash($text)
  227. {
  228. if (!empty($this->key)) {
  229. switch ( CRYPT_HASH_MODE ) {
  230. case CRYPT_HASH_MODE_MHASH:
  231. $output = mhash($this->hash, $text, $this->key);
  232. break;
  233. case CRYPT_HASH_MODE_HASH:
  234. $output = hash_hmac($this->hash, $text, $this->key, true);
  235. break;
  236. case CRYPT_HASH_MODE_INTERNAL:
  237. $hash = $this->hash;
  238. /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
  239. resultant L byte string as the actual key to HMAC."
  240. -- http://tools.ietf.org/html/rfc2104#section-2 */
  241. $key = strlen($this->key) > $this->b ? $hash($this->key) : $this->key;
  242. $key = str_pad($key, $this->b, chr(0));// step 1
  243. $temp = $this->ipad ^ $key; // step 2
  244. $temp .= $text; // step 3
  245. $temp = pack('H*', $hash($temp)); // step 4
  246. $output = $this->opad ^ $key; // step 5
  247. $output.= $temp; // step 6
  248. $output = pack('H*', $hash($output)); // step 7
  249. }
  250. } else {
  251. switch ( CRYPT_HASH_MODE ) {
  252. case CRYPT_HASH_MODE_MHASH:
  253. $output = mhash($this->hash, $text);
  254. break;
  255. case CRYPT_HASH_MODE_MHASH:
  256. $output = hash($this->hash, $text, true);
  257. break;
  258. case CRYPT_HASH_MODE_INTERNAL:
  259. $hash = $this->hash;
  260. $output = pack('H*', $hash($output));
  261. }
  262. }
  263. return substr($output, 0, $this->l);
  264. }
  265. }