Encrypt.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /**
  3. * Encryption Class for KO7.
  4. * - Handles Encryption instances and proxies encrypt/decrypt functions
  5. *
  6. * Example Usage:
  7. * $engine = Encrypt::instance();
  8. * $msg = $engine->encode('Crypt this!'); -> will return an encrypted string
  9. * $text = $engine->decode($msg); -> will return "Crypt this!"
  10. *
  11. * @package KO7/Encrypt
  12. * @category Security
  13. *
  14. * @copyright (c) 2007-2012 Kohana Team
  15. * @copyright (c) 2016-2018 Koseven Team
  16. * @license https://koseven.dev/LICENSE
  17. */
  18. class KO7_Encrypt {
  19. /**
  20. * Name of default config instance
  21. * @var string
  22. */
  23. public static $default = 'default';
  24. /**
  25. * Name of default engine to use
  26. * @var string
  27. */
  28. public static $default_engine = 'openssl';
  29. /**
  30. * Encrypt class instances
  31. * @var array
  32. */
  33. public static $instances = [];
  34. /**
  35. * Engine Name
  36. * @var string
  37. */
  38. private $_name;
  39. /**
  40. * Encryption engine
  41. * @var KO7_Encrypt_Engine
  42. */
  43. private $_engine;
  44. /**
  45. * Creates a new Encrypt Engine instance.
  46. *
  47. * @param string $name Engine Name
  48. * @param array $config Configuration
  49. *
  50. * @throws KO7_Exception
  51. */
  52. public function __construct(string $name, array $config)
  53. {
  54. // Get Driver Type
  55. $config['type'] = $config['type'] ?? self::$default_engine;
  56. // Set the engine class name
  57. $engine_name = 'Encrypt_Engine_'.ucfirst($config['type']);
  58. // Create the engine class
  59. $this->_name = $name;
  60. // Since user can define class via string we need to check if it exists
  61. if (!class_exists($engine_name)) {
  62. throw new KO7_Exception('Encryption type: :name defined in the encryption configuratin does not exist.', [
  63. ':name' => $engine_name,
  64. ]);
  65. }
  66. $this->_engine = new $engine_name($config);
  67. // make sure class is instance of KO7_Encrypt_Engine
  68. if (!$this->_engine instanceof KO7_Encrypt_Engine) {
  69. // @codeCoverageIgnoreStart
  70. throw new KO7_Exception('Encryption type: :name defined in the encryption configuration is not a valid type/driver class.', [
  71. ':name' => $engine_name,
  72. ]);
  73. // @codeCoverageIgnoreEnd
  74. }
  75. }
  76. /**
  77. * Returns a singleton instance of Encrypt. An encryption key must be
  78. * provided in your "encrypt" configuration file.
  79. * $encrypt = Encrypt::instance();
  80. *
  81. * @param string $name Configuration group name
  82. * @param array|null $config Configuration
  83. *
  84. * @return KO7_Encrypt
  85. * @throws KO7_Exception
  86. */
  87. public static function instance(string $name = NULL, array $config = NULL)
  88. {
  89. if ($name === NULL) {
  90. // Use the default instance name
  91. $name = self::$default;
  92. }
  93. if (!isset(self::$instances[$name])) {
  94. if ($config === NULL) {
  95. // Load the configuration data
  96. $config = KO7::$config->load('encrypt')->$name;
  97. }
  98. if (!isset($config['key']) || empty($config['key'])) {
  99. // No default encryption key is provided!
  100. throw new KO7_Exception('No encryption key is defined in the encryption configuration group: :group',
  101. [':group' => $name]);
  102. }
  103. // Create a new instance
  104. self::$instances[$name] = new self($name, $config);
  105. }
  106. return self::$instances[$name];
  107. }
  108. /**
  109. * Encrypts a string and returns an encrypted string that can be decoded.
  110. * $data = $encrypt->encode($message);
  111. * The encrypted binary data is encoded using [base64](http://php.net/base64_encode)
  112. * to convert it to a string. This string can be stored in a database,
  113. * displayed, and passed using most other means without corruption.
  114. * WARNING! The $iv variable is for testing purposes only, do not use this variable
  115. * unless you REALLY know what you are doing.
  116. *
  117. * @param string $message Message to be encrypted
  118. * @param string|null $iv Initialization Vector
  119. *
  120. * @return null|string
  121. * @throws Exception
  122. */
  123. public function encode(string $message, string $iv = NULL)
  124. {
  125. if ($iv === NULL) {
  126. $iv = $this->_engine->create_iv();
  127. }
  128. return $this->_engine->encrypt($message, $iv);
  129. }
  130. /**
  131. * Decrypts an encoded string back to its original value.
  132. * $data = $encrypt->decode($ciphertext);
  133. *
  134. * @param string $ciphertext Text to decrypt
  135. *
  136. * @return null|string
  137. */
  138. public function decode(string $ciphertext)
  139. {
  140. return $this->_engine->decrypt($ciphertext);
  141. }
  142. /**
  143. * Returns text representation of Encrypt class
  144. *
  145. * @return string
  146. */
  147. public function __toString(): string
  148. {
  149. return get_class($this->_engine).' ('.$this->_name.')';
  150. }
  151. }