PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/qcodo/framework_objects/QCryptography.inc

https://github.com/eliego/oqtopus
PHP | 199 lines | 114 code | 32 blank | 53 comment | 22 complexity | 102f1e9429ad66428435ae4c05fde80f 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 = "Default!Key";
  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. set_error_handler('QcodoHandleError', 0);
  78. $intCurrentLevel = error_reporting();
  79. error_reporting(0);
  80. $strIv = mcrypt_create_iv($intIvSize, self::$RandomSource);
  81. error_reporting($intCurrentLevel);
  82. restore_error_handler();
  83. // If the RandomNumGenerator didn't work, we revert back to using MCRYPT_RAND
  84. if (strlen($strIv) != $intIvSize) {
  85. srand();
  86. $strIv = mcrypt_create_iv($intIvSize, MCRYPT_RAND);
  87. }
  88. } else {
  89. srand();
  90. $strIv = mcrypt_create_iv($intIvSize, MCRYPT_RAND);
  91. }
  92. $this->strIv = $strIv;
  93. // Determine KeySize length
  94. $intKeySize = mcrypt_enc_get_key_size($this->objMcryptModule);
  95. // Create the Key Based on Key Passed In
  96. $this->strKey = substr(md5($strKey), 0, $intKeySize);
  97. }
  98. public function Encrypt($strData) {
  99. // Initialize Encryption
  100. $intReturnValue = mcrypt_generic_init($this->objMcryptModule, $this->strKey, $this->strIv);
  101. if (($intReturnValue === false) || ($intReturnValue < 0))
  102. throw new QCryptographyException('Incorrect Parameters used in LibMcrypt Initialization');
  103. // Add Length to strData
  104. $strData = strlen($strData) . '/' . $strData;
  105. $strEncryptedData = mcrypt_generic($this->objMcryptModule, $strData);
  106. if ($this->blnBase64) {
  107. $strEncryptedData = base64_encode($strEncryptedData);
  108. $strEncryptedData = str_replace('+', '-', $strEncryptedData);
  109. $strEncryptedData = str_replace('/', '_', $strEncryptedData);
  110. $strEncryptedData = str_replace('=', '', $strEncryptedData);
  111. }
  112. // Deinitialize Encryption
  113. if (!mcrypt_generic_deinit($this->objMcryptModule))
  114. throw new QCryptographyException('Unable to deinitialize encryption buffer');
  115. return $strEncryptedData;
  116. }
  117. public function Decrypt($strEncryptedData) {
  118. // Initialize Encryption
  119. $intReturnValue = mcrypt_generic_init($this->objMcryptModule, $this->strKey, $this->strIv);
  120. if (($intReturnValue === false) || ($intReturnValue < 0))
  121. throw new QCryptographyException('Incorrect Parameters used in LibMcrypt Initialization');
  122. if ($this->blnBase64) {
  123. $strEncryptedData = str_replace('_', '/', $strEncryptedData);
  124. $strEncryptedData = str_replace('-', '+', $strEncryptedData);
  125. $strEncryptedData = base64_decode($strEncryptedData);
  126. }
  127. $intBlockSize = mcrypt_enc_get_block_size($this->objMcryptModule);
  128. $strDecryptedData = mdecrypt_generic($this->objMcryptModule, $strEncryptedData);
  129. // Figure Out Length and Truncate
  130. $intPosition = strpos($strDecryptedData, '/');
  131. if (!$intPosition)
  132. throw new QCryptographyException('Invalid Length Header in Decrypted Data');
  133. $intLength = substr($strDecryptedData, 0, $intPosition);
  134. $strDecryptedData = substr($strDecryptedData, $intPosition + 1);
  135. $strDecryptedData = substr($strDecryptedData, 0, $intLength);
  136. // Deinitialize Encryption
  137. if (!mcrypt_generic_deinit($this->objMcryptModule))
  138. throw new QCryptographyException('Unable to deinitialize encryption buffer');
  139. return $strDecryptedData;
  140. }
  141. public function EncryptFile($strFile) {
  142. if (file_exists($strFile)) {
  143. $strData = file_get_contents($strFile);
  144. return $this->Encrypt($strData);
  145. } else
  146. throw new QCallerException('File does not exist: ' . $strFile);
  147. }
  148. public function DecryptFile($strFile) {
  149. if (file_exists($strFile)) {
  150. $strEncryptedData = file_get_contents($strFile);
  151. return $this->Decrypt($strEncryptedData);
  152. } else
  153. throw new QCallerException('File does not exist: ' . $strFile);
  154. }
  155. public function __destruct() {
  156. if ($this->objMcryptModule) {
  157. // Ignore All Warnings
  158. set_error_handler('QcodoHandleError', 0);
  159. $intCurrentLevel = error_reporting();
  160. error_reporting(0);
  161. mcrypt_module_close($this->objMcryptModule);
  162. error_reporting($intCurrentLevel);
  163. restore_error_handler();
  164. }
  165. }
  166. }
  167. ?>