PageRenderTime 38ms CodeModel.GetById 4ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/crypt/cipher/mcrypt.php

http://github.com/joomla/joomla-platform
PHP | 175 lines | 58 code | 23 blank | 94 comment | 7 complexity | ea688fd0364a720840efc313dbf8d088 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Crypt
  5. *
  6. * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * JCrypt cipher for mcrypt algorithm encryption, decryption and key generation.
  12. *
  13. * @package Joomla.Platform
  14. * @subpackage Crypt
  15. * @since 12.1
  16. */
  17. abstract class JCryptCipherMcrypt implements JCryptCipher
  18. {
  19. /**
  20. * @var integer The mcrypt cipher constant.
  21. * @see http://www.php.net/manual/en/mcrypt.ciphers.php
  22. * @since 12.1
  23. */
  24. protected $type;
  25. /**
  26. * @var integer The mcrypt block cipher mode.
  27. * @see http://www.php.net/manual/en/mcrypt.constants.php
  28. * @since 12.1
  29. */
  30. protected $mode;
  31. /**
  32. * @var string The JCrypt key type for validation.
  33. * @since 12.1
  34. */
  35. protected $keyType;
  36. /**
  37. * Constructor.
  38. *
  39. * @since 12.1
  40. * @throws RuntimeException
  41. */
  42. public function __construct()
  43. {
  44. if (!is_callable('mcrypt_encrypt'))
  45. {
  46. throw new RuntimeException('The mcrypt extension is not available.');
  47. }
  48. }
  49. /**
  50. * Method to decrypt a data string.
  51. *
  52. * @param string $data The encrypted string to decrypt.
  53. * @param JCryptKey $key The key object to use for decryption.
  54. *
  55. * @return string The decrypted data string.
  56. *
  57. * @since 12.1
  58. */
  59. public function decrypt($data, JCryptKey $key)
  60. {
  61. // Validate key.
  62. if ($key->type != $this->keyType)
  63. {
  64. throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected ' . $this->keyType . '.');
  65. }
  66. // Decrypt the data.
  67. $decrypted = trim(mcrypt_decrypt($this->type, $key->private, $data, $this->mode, $key->public));
  68. return $decrypted;
  69. }
  70. /**
  71. * Method to encrypt a data string.
  72. *
  73. * @param string $data The data string to encrypt.
  74. * @param JCryptKey $key The key object to use for encryption.
  75. *
  76. * @return string The encrypted data string.
  77. *
  78. * @since 12.1
  79. */
  80. public function encrypt($data, JCryptKey $key)
  81. {
  82. // Validate key.
  83. if ($key->type != $this->keyType)
  84. {
  85. throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected ' . $this->keyType . '.');
  86. }
  87. // Encrypt the data.
  88. $encrypted = mcrypt_encrypt($this->type, $key->private, $data, $this->mode, $key->public);
  89. return $encrypted;
  90. }
  91. /**
  92. * Method to generate a new encryption key object.
  93. *
  94. * @param array $options Key generation options.
  95. *
  96. * @return JCryptKey
  97. *
  98. * @since 12.1
  99. */
  100. public function generateKey(array $options = array())
  101. {
  102. // Create the new encryption key object.
  103. $key = new JCryptKey($this->keyType);
  104. // Generate an initialisation vector based on the algorithm.
  105. $key->public = mcrypt_create_iv(mcrypt_get_iv_size($this->type, $this->mode));
  106. // Get the salt and password setup.
  107. $salt = (isset($options['salt'])) ? $options['salt'] : substr(pack("h*", md5(mt_rand())), 0, 16);
  108. $password = (isset($options['password'])) ? $options['password'] : 'J00ml4R0ck$!';
  109. // Generate the derived key.
  110. $key->private = $this->pbkdf2($password, $salt, mcrypt_get_key_size($this->type, $this->mode));
  111. return $key;
  112. }
  113. /**
  114. * PBKDF2 Implementation for deriving keys.
  115. *
  116. * @param string $p Password
  117. * @param string $s Salt
  118. * @param integer $kl Key length
  119. * @param integer $c Iteration count
  120. * @param string $a Hash algorithm
  121. *
  122. * @return string The derived key.
  123. *
  124. * @see http://en.wikipedia.org/wiki/PBKDF2
  125. * @see http://www.ietf.org/rfc/rfc2898.txt
  126. * @since 12.1
  127. */
  128. public function pbkdf2($p, $s, $kl, $c = 10000, $a = 'sha256')
  129. {
  130. // Hash length.
  131. $hl = strlen(hash($a, null, true));
  132. // Key blocks to compute.
  133. $kb = ceil($kl / $hl);
  134. // Derived key.
  135. $dk = '';
  136. // Create the key.
  137. for ($block = 1; $block <= $kb; $block++)
  138. {
  139. // Initial hash for this block.
  140. $ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
  141. // Perform block iterations.
  142. for ($i = 1; $i < $c; $i++)
  143. {
  144. $ib ^= ($b = hash_hmac($a, $b, $p, true));
  145. }
  146. // Append the iterated block.
  147. $dk .= $ib;
  148. }
  149. // Return derived key of correct length.
  150. return substr($dk, 0, $kl);
  151. }
  152. }