crypter.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php namespace Laravel\Security;
  2. class Crypter {
  3. /**
  4. * The encryption cipher.
  5. *
  6. * @var string
  7. */
  8. public $cipher;
  9. /**
  10. * The encryption mode.
  11. *
  12. * @var string
  13. */
  14. public $mode;
  15. /**
  16. * The encryption key.
  17. *
  18. * @var string
  19. */
  20. public $key;
  21. /**
  22. * Create a new Crypter instance.
  23. *
  24. * A valid cipher and mode supported by the Mcrypt extension must be given to the constructor.
  25. * Also, an encryption key (typically from the application configuration) must be specified.
  26. *
  27. * @param string $cipher
  28. * @param string $mode
  29. * @param string $key
  30. * @return void
  31. */
  32. public function __construct($cipher, $mode, $key)
  33. {
  34. $this->key = $key;
  35. $this->mode = $mode;
  36. $this->cipher = $cipher;
  37. if (trim((string) $this->key) === '')
  38. {
  39. throw new \Exception('The encryption class may not be used without an encryption key.');
  40. }
  41. }
  42. /**
  43. * Encrypt a string using Mcrypt.
  44. *
  45. * The string will be encrypted using the cipher and mode specified when the crypter
  46. * instance was created, and the final result will be base64 encoded.
  47. *
  48. * <code>
  49. * // Encrypt a string using the Mcrypt PHP extension
  50. * $encrypted = Crypter::encrpt('secret');
  51. * </code>
  52. *
  53. * @param string $value
  54. * @return string
  55. */
  56. public function encrypt($value)
  57. {
  58. // Determine the most appropriate random number generator for the operating
  59. // system and environment the application is running on.
  60. if (defined('MCRYPT_DEV_URANDOM'))
  61. {
  62. $randomizer = MCRYPT_DEV_URANDOM;
  63. }
  64. elseif (defined('MCRYPT_DEV_RANDOM'))
  65. {
  66. $randomizer = MCRYPT_DEV_RANDOM;
  67. }
  68. else
  69. {
  70. $randomizer = MCRYPT_RAND;
  71. }
  72. $iv = mcrypt_create_iv($this->iv_size(), $randomizer);
  73. return base64_encode($iv.mcrypt_encrypt($this->cipher, $this->key, $value, $this->mode, $iv));
  74. }
  75. /**
  76. * Decrypt a string using Mcrypt.
  77. *
  78. * The string will be decrypted using the cipher and mode specified when the crypter was created.
  79. *
  80. * <code>
  81. * // Decrypt a string using the Mcrypt PHP extension
  82. * $decrypted = Crypter::decrypt($secret);
  83. * </code>
  84. *
  85. * @param string $value
  86. * @return string
  87. */
  88. public function decrypt($value)
  89. {
  90. // Since all encrypted strings generated by this class are base64 encoded, we will
  91. // first attempt to base64 decode the string. If we can't do it, we'll bail out.
  92. if ( ! is_string($value = base64_decode($value, true)))
  93. {
  94. throw new \Exception('Decryption error. Input value is not valid base64 data.');
  95. }
  96. // Extract the input vector and the encrypted string from the value
  97. list($iv, $value) = array(substr($value, 0, $this->iv_size()), substr($value, $this->iv_size()));
  98. return rtrim(mcrypt_decrypt($this->cipher, $this->key, $value, $this->mode, $iv), "\0");
  99. }
  100. /**
  101. * Get the input vector size for the cipher and mode.
  102. *
  103. * Different ciphers and modes use varying lengths of input vectors.
  104. *
  105. * @return int
  106. */
  107. private function iv_size()
  108. {
  109. return mcrypt_get_iv_size($this->cipher, $this->mode);
  110. }
  111. }