SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/Encrypt.php

Copyright (C) 2017 Karmabunny Pty Ltd.

This file is a part of SproutCMS.

SproutCMS is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either
version 2 of the License, or (at your option) any later version.

For more information, visit <http://getsproutcms.com>.

This class was originally from Kohana 2.3.4
Copyright 2007-2008 Kohana Team
  1. <?php
  2. /**
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  *
  13.  * This class was originally from Kohana 2.3.4
  14.  * Copyright 2007-2008 Kohana Team
  15.  */
  16. namespace Sprout\Helpers;
  17.  
  18. use Kohana;
  19. use Kohana_Exception;
  20.  
  21.  
  22. /**
  23.  * The Encrypt library provides two-way encryption of text and binary strings
  24.  * using the MCrypt extension ({@see http://php.net/mcrypt})
  25.  */
  26. class Encrypt
  27. {
  28.  
  29. // OS-dependant RAND type to use
  30. protected static $rand;
  31.  
  32. // Configuration
  33. protected $config;
  34.  
  35. /**
  36.   * Returns a singleton instance of Encrypt.
  37.   *
  38.   * @param array configuration options
  39.   * @return Encrypt
  40.   */
  41. public static function instance($config = NULL)
  42. {
  43. static $instance;
  44.  
  45. // Create the singleton
  46. empty($instance) and $instance = new Encrypt((array) $config);
  47.  
  48. return $instance;
  49. }
  50.  
  51. /**
  52.   * Loads encryption configuration and validates the data.
  53.   *
  54.   * @param array|string custom configuration or config group name
  55.   * @throws Kohana_Exception
  56.   */
  57. public function __construct($config = FALSE)
  58. {
  59. if ( ! defined('MCRYPT_ENCRYPT'))
  60. throw new Kohana_Exception('encrypt.requires_mcrypt');
  61.  
  62. if (is_string($config))
  63. {
  64. $name = $config;
  65.  
  66. // Test the config group name
  67. if (($config = Kohana::config('encryption.'.$config)) === NULL)
  68. throw new Kohana_Exception('encrypt.undefined_group', $name);
  69. }
  70.  
  71. if (is_array($config))
  72. {
  73. // Append the default configuration options
  74. $config += Kohana::config('encryption.default');
  75. }
  76. else
  77. {
  78. // Load the default group
  79. $config = Kohana::config('encryption.default');
  80. }
  81.  
  82. if (empty($config['key']))
  83. throw new Kohana_Exception('encrypt.no_encryption_key');
  84.  
  85. // Find the max length of the key, based on cipher and mode
  86. $size = mcrypt_get_key_size($config['cipher'], $config['mode']);
  87.  
  88. if (strlen($config['key']) > $size)
  89. {
  90. // Shorten the key to the maximum size
  91. $config['key'] = substr($config['key'], 0, $size);
  92. }
  93.  
  94. // Find the initialization vector size
  95. $config['iv_size'] = mcrypt_get_iv_size($config['cipher'], $config['mode']);
  96.  
  97. // Cache the config in the object
  98. $this->config = $config;
  99. }
  100.  
  101. /**
  102.   * Encrypts a string and returns an encrypted string that can be decoded.
  103.   *
  104.   * @param string data to be encrypted
  105.   * @return string encrypted data
  106.   */
  107. public function encode($data)
  108. {
  109. // Set the rand type if it has not already been set
  110. if (Encrypt::$rand === NULL)
  111. {
  112. if (DIRECTORY_SEPARATOR === '\\')
  113. {
  114. // Windows only supports the system random number generator
  115. Encrypt::$rand = MCRYPT_RAND;
  116. }
  117. else
  118. {
  119. if (defined('MCRYPT_DEV_URANDOM'))
  120. {
  121. // Use /dev/urandom
  122. Encrypt::$rand = MCRYPT_DEV_URANDOM;
  123. }
  124. elseif (defined('MCRYPT_DEV_RANDOM'))
  125. {
  126. // Use /dev/random
  127. Encrypt::$rand = MCRYPT_DEV_RANDOM;
  128. }
  129. else
  130. {
  131. // Use the system random number generator
  132. Encrypt::$rand = MCRYPT_RAND;
  133. }
  134. }
  135. }
  136.  
  137. if (Encrypt::$rand === MCRYPT_RAND)
  138. {
  139. // The system random number generator must always be seeded each
  140. // time it is used, or it will not produce true random results
  141. }
  142.  
  143. // Create a random initialization vector of the proper size for the current cipher
  144. $iv = mcrypt_create_iv($this->config['iv_size'], Encrypt::$rand);
  145.  
  146. // Encrypt the data using the configured options and generated iv
  147. $data = mcrypt_encrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv);
  148.  
  149. // Use base64 encoding to convert to a string
  150. return base64_encode($iv.$data);
  151. }
  152.  
  153. /**
  154.   * Decrypts an encoded string back to its original value.
  155.   *
  156.   * @param string encoded string to be decrypted
  157.   * @return string decrypted data
  158.   */
  159. public function decode($data)
  160. {
  161. // Convert the data back to binary
  162. $data = base64_decode($data);
  163.  
  164. // Extract the initialization vector from the data
  165. $iv = substr($data, 0, $this->config['iv_size']);
  166.  
  167. // Remove the iv from the data
  168. $data = substr($data, $this->config['iv_size']);
  169.  
  170. // Return the decrypted data, trimming the \0 padding bytes from the end of the data
  171. return rtrim(mcrypt_decrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv), "\0");
  172. }
  173.  
  174. } // End Encrypt
  175.