Joomla Platform  13.1
Documentation des API du framework Joomla Platform
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
mcrypt.php
Aller à la documentation de ce fichier.
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 
10 defined('JPATH_PLATFORM') or die;
11 
12 /**
13  * JCrypt cipher for mcrypt algorithm encryption, decryption and key generation.
14  *
15  * @package Joomla.Platform
16  * @subpackage Crypt
17  * @since 12.1
18  */
19 abstract class JCryptCipherMcrypt implements JCryptCipher
20 {
21  /**
22  * @var integer The mcrypt cipher constant.
23  * @see http://www.php.net/manual/en/mcrypt.ciphers.php
24  * @since 12.1
25  */
26  protected $type;
27 
28  /**
29  * @var integer The mcrypt block cipher mode.
30  * @see http://www.php.net/manual/en/mcrypt.constants.php
31  * @since 12.1
32  */
33  protected $mode;
34 
35  /**
36  * @var string The JCrypt key type for validation.
37  * @since 12.1
38  */
39  protected $keyType;
40 
41  /**
42  * Constructor.
43  *
44  * @since 12.1
45  * @throws RuntimeException
46  */
47  public function __construct()
48  {
49  if (!is_callable('mcrypt_encrypt'))
50  {
51  throw new RuntimeException('The mcrypt extension is not available.');
52  }
53  }
54 
55  /**
56  * Method to decrypt a data string.
57  *
58  * @param string $data The encrypted string to decrypt.
59  * @param JCryptKey $key The key object to use for decryption.
60  *
61  * @return string The decrypted data string.
62  *
63  * @since 12.1
64  */
65  public function decrypt($data, JCryptKey $key)
66  {
67  // Validate key.
68  if ($key->type != $this->keyType)
69  {
70  throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected ' . $this->keyType . '.');
71  }
72 
73  // Decrypt the data.
74  $decrypted = trim(mcrypt_decrypt($this->type, $key->private, $data, $this->mode, $key->public));
75 
76  return $decrypted;
77  }
78 
79  /**
80  * Method to encrypt a data string.
81  *
82  * @param string $data The data string to encrypt.
83  * @param JCryptKey $key The key object to use for encryption.
84  *
85  * @return string The encrypted data string.
86  *
87  * @since 12.1
88  */
89  public function encrypt($data, JCryptKey $key)
90  {
91  // Validate key.
92  if ($key->type != $this->keyType)
93  {
94  throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected ' . $this->keyType . '.');
95  }
96 
97  // Encrypt the data.
98  $encrypted = mcrypt_encrypt($this->type, $key->private, $data, $this->mode, $key->public);
99 
100  return $encrypted;
101  }
102 
103  /**
104  * Method to generate a new encryption key object.
105  *
106  * @param array $options Key generation options.
107  *
108  * @return JCryptKey
109  *
110  * @since 12.1
111  */
112  public function generateKey(array $options = array())
113  {
114  // Create the new encryption key object.
115  $key = new JCryptKey($this->keyType);
116 
117  // Generate an initialisation vector based on the algorithm.
118  $key->public = mcrypt_create_iv(mcrypt_get_iv_size($this->type, $this->mode));
119 
120  // Get the salt and password setup.
121  $salt = (isset($options['salt'])) ? $options['salt'] : substr(pack("h*", md5(mt_rand())), 0, 16);
122  $password = (isset($options['password'])) ? $options['password'] : 'J00ml4R0ck$!';
123 
124  // Generate the derived key.
125  $key->private = $this->pbkdf2($password, $salt, mcrypt_get_key_size($this->type, $this->mode));
126 
127  return $key;
128  }
129 
130  /**
131  * PBKDF2 Implementation for deriving keys.
132  *
133  * @param string $p Password
134  * @param string $s Salt
135  * @param integer $kl Key length
136  * @param integer $c Iteration count
137  * @param string $a Hash algorithm
138  *
139  * @return string The derived key.
140  *
141  * @see http://en.wikipedia.org/wiki/PBKDF2
142  * @see http://www.ietf.org/rfc/rfc2898.txt
143  * @since 12.1
144  */
145  public function pbkdf2($p, $s, $kl, $c = 10000, $a = 'sha256')
146  {
147  // Hash length.
148  $hl = strlen(hash($a, null, true));
149 
150  // Key blocks to compute.
151  $kb = ceil($kl / $hl);
152 
153  // Derived key.
154  $dk = '';
155 
156  // Create the key.
157  for ($block = 1; $block <= $kb; $block++)
158  {
159  // Initial hash for this block.
160  $ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
161 
162  // Perform block iterations.
163  for ($i = 1; $i < $c; $i++)
164  {
165  $ib ^= ($b = hash_hmac($a, $b, $p, true));
166  }
167 
168  // Append the iterated block.
169  $dk .= $ib;
170  }
171 
172  // Return derived key of correct length.
173  return substr($dk, 0, $kl);
174  }
175 }