/includes/qcodo/_core/framework/QCryptography.class.php

https://github.com/quinta/qcodo · PHP · 189 lines · 104 code · 32 blank · 53 comment · 22 complexity · ecaa0da5e9cccb345a704308e446a792 MD5 · raw file

  1. <?php
  2. // Requires libmcrypt v2.4.x or higher
  3. class QCryptographyException extends QCallerException {}
  4. class QCryptography extends QBaseClass {
  5. protected $objMcryptModule;
  6. protected $blnBase64;
  7. protected $strKey;
  8. protected $strIv;
  9. /**
  10. * Default Cipher for any new QCryptography instances that get constructed
  11. * @var string Cipher
  12. */
  13. public static $Cipher = MCRYPT_TRIPLEDES;
  14. /**
  15. * Default Mode for any new QCryptography instances that get constructed
  16. * @var string Mode
  17. */
  18. public static $Mode = MCRYPT_MODE_ECB;
  19. /**
  20. * The Random Number Generator the library uses to generate the IV:
  21. * - MCRYPT_DEV_RANDOM = /dev/random (only on *nix systems)
  22. * - MCRYPT_DEV_URANDOM = /dev/urandom (only on *nix systems)
  23. * - MCRYPT_RAND = the internal PHP srand() mechanism
  24. * (on Windows, you *must* use MCRYPT_RAND, b/c /dev/random and /dev/urandom doesn't exist)
  25. *
  26. * TODO: there appears to be some /dev/random locking issues on the Qcodo development
  27. * environment (using Fedora Core 3 with PHP 5.0.4 and LibMcrypt 2.5.7). Because of this,
  28. * we are using MCRYPT_RAND be default. Feel free to change to to /dev/*random at your own risk.
  29. *
  30. * @var string RandomSource
  31. */
  32. public static $RandomSource = MCRYPT_RAND;
  33. /**
  34. * Default Base64 mode for any new QCryptography instances that get constructed.
  35. *
  36. * This is similar to MIME-based Base64 encoding/decoding, but is safe to use
  37. * in URLs, POST/GET data, and any other text-based stream.
  38. *
  39. * Note that by setting Base64 to true, it will result in an encrypted data string
  40. * that is 33% larger.
  41. * @var string Base64
  42. */
  43. public static $Base64 = true;
  44. /**
  45. * Default Key for any new QCryptography instances that get constructed
  46. * @var string Key
  47. */
  48. public static $Key = "qc0Do!d3F@lT.k3Y";
  49. public function __construct($strKey = null, $blnBase64 = null, $strCipher = null, $strMode = null) {
  50. // Get the Key
  51. if (is_null($strKey))
  52. $strKey = self::$Key;
  53. // Get the Base64 Flag
  54. try {
  55. if (is_null($blnBase64))
  56. $this->blnBase64 = QType::Cast(self::$Base64, QType::Boolean);
  57. else
  58. $this->blnBase64 = QType::Cast($blnBase64, QType::Boolean);
  59. } catch (QCallerException $objExc) {
  60. $objExc->IncrementOffset();
  61. throw $objExc;
  62. }
  63. // Get the Cipher
  64. if (is_null($strCipher))
  65. $strCipher = self::$Cipher;
  66. // Get the Mode
  67. if (is_null($strMode))
  68. $strMode = self::$Mode;
  69. $this->objMcryptModule = mcrypt_module_open($strCipher, null, $strMode, null);
  70. if (!$this->objMcryptModule)
  71. throw new QCryptographyException('Unable to open LibMcrypt Module');
  72. // Determine IV Size
  73. $intIvSize = mcrypt_enc_get_iv_size($this->objMcryptModule);
  74. // Create the IV
  75. if (self::$RandomSource != MCRYPT_RAND) {
  76. // Ignore All Warnings
  77. $strIv = @mcrypt_create_iv($intIvSize, self::$RandomSource);
  78. // If the RandomNumGenerator didn't work, we revert back to using MCRYPT_RAND
  79. if (strlen($strIv) != $intIvSize) {
  80. srand();
  81. $strIv = mcrypt_create_iv($intIvSize, MCRYPT_RAND);
  82. }
  83. } else {
  84. srand();
  85. $strIv = mcrypt_create_iv($intIvSize, MCRYPT_RAND);
  86. }
  87. $this->strIv = $strIv;
  88. // Determine KeySize length
  89. $intKeySize = mcrypt_enc_get_key_size($this->objMcryptModule);
  90. // Create the Key Based on Key Passed In
  91. $this->strKey = substr(md5($strKey), 0, $intKeySize);
  92. }
  93. public function Encrypt($strData) {
  94. // Initialize Encryption
  95. $intReturnValue = mcrypt_generic_init($this->objMcryptModule, $this->strKey, $this->strIv);
  96. if (($intReturnValue === false) || ($intReturnValue < 0))
  97. throw new QCryptographyException('Incorrect Parameters used in LibMcrypt Initialization');
  98. // Add Length to strData
  99. $strData = strlen($strData) . '/' . $strData;
  100. $strEncryptedData = mcrypt_generic($this->objMcryptModule, $strData);
  101. if ($this->blnBase64) {
  102. $strEncryptedData = base64_encode($strEncryptedData);
  103. $strEncryptedData = str_replace('+', '-', $strEncryptedData);
  104. $strEncryptedData = str_replace('/', '_', $strEncryptedData);
  105. $strEncryptedData = str_replace('=', '', $strEncryptedData);
  106. }
  107. // Deinitialize Encryption
  108. if (!mcrypt_generic_deinit($this->objMcryptModule))
  109. throw new QCryptographyException('Unable to deinitialize encryption buffer');
  110. return $strEncryptedData;
  111. }
  112. public function Decrypt($strEncryptedData) {
  113. // Initialize Encryption
  114. $intReturnValue = mcrypt_generic_init($this->objMcryptModule, $this->strKey, $this->strIv);
  115. if (($intReturnValue === false) || ($intReturnValue < 0))
  116. throw new QCryptographyException('Incorrect Parameters used in LibMcrypt Initialization');
  117. if ($this->blnBase64) {
  118. $strEncryptedData = str_replace('_', '/', $strEncryptedData);
  119. $strEncryptedData = str_replace('-', '+', $strEncryptedData);
  120. $strEncryptedData = base64_decode($strEncryptedData);
  121. }
  122. $intBlockSize = mcrypt_enc_get_block_size($this->objMcryptModule);
  123. $strDecryptedData = mdecrypt_generic($this->objMcryptModule, $strEncryptedData);
  124. // Figure Out Length and Truncate
  125. $intPosition = strpos($strDecryptedData, '/');
  126. if (!$intPosition)
  127. throw new QCryptographyException('Invalid Length Header in Decrypted Data');
  128. $intLength = substr($strDecryptedData, 0, $intPosition);
  129. $strDecryptedData = substr($strDecryptedData, $intPosition + 1);
  130. $strDecryptedData = substr($strDecryptedData, 0, $intLength);
  131. // Deinitialize Encryption
  132. if (!mcrypt_generic_deinit($this->objMcryptModule))
  133. throw new QCryptographyException('Unable to deinitialize encryption buffer');
  134. return $strDecryptedData;
  135. }
  136. public function EncryptFile($strFile) {
  137. if (file_exists($strFile)) {
  138. $strData = file_get_contents($strFile);
  139. return $this->Encrypt($strData);
  140. } else
  141. throw new QCallerException('File does not exist: ' . $strFile);
  142. }
  143. public function DecryptFile($strFile) {
  144. if (file_exists($strFile)) {
  145. $strEncryptedData = file_get_contents($strFile);
  146. return $this->Decrypt($strEncryptedData);
  147. } else
  148. throw new QCallerException('File does not exist: ' . $strFile);
  149. }
  150. public function __destruct() {
  151. if ($this->objMcryptModule) {
  152. // Ignore All Warnings
  153. @mcrypt_module_close($this->objMcryptModule);
  154. }
  155. }
  156. }
  157. ?>