/mod/turningtech/lib/helpers/EncryptionHelper.php

https://github.com/jarednipper/HSU-common-code · PHP · 271 lines · 149 code · 31 blank · 91 comment · 53 complexity · c8b796f383f6d0304f645c55a9c3f417 MD5 · raw file

  1. <?php
  2. /*******
  3. * Helper for support of encrypt/decryption-related functionality.
  4. * @author jacob
  5. *
  6. * NOTE: callers which include/require this class MUST also include/require the following:
  7. * - [moodle root]/config.php
  8. * - mod/turningtech/lib.php
  9. **/
  10. /**
  11. * decrypt a single string for ResponseWare
  12. * @param $str the string to decrypt
  13. * @return string
  14. */
  15. function decryptResponseWareString($str) {
  16. if( ! TURNINGTECH_ENABLE_DECRYPTION ) return $str;
  17. $crunch = new TurningTechEncryptionHelper();
  18. $crunch->key = base64_decode( 'iZRKTcYfw9G2DGrdymD23w==' );
  19. $crunch->iv = base64_decode( 'DvNdhsQOmHhMn6ZESNTTlw==' );
  20. $crunch->mode = MCRYPT_MODE_CBC;
  21. $crunch->dobase64 = false;
  22. $crunch->doPKCS5 = true;
  23. return $crunch->decryptString( $str );
  24. }
  25. /**
  26. * decrypt a list of strings for ResponseWare
  27. * @param $strings array
  28. * @return string array
  29. */
  30. function decryptResponseWareStrings($strings) {
  31. if( ! TURNINGTECH_ENABLE_DECRYPTION ) return $strings;
  32. for($i= 0; $i<count($strings); $i++) {
  33. $strings[$i] = decryptResponseWareString($strings[$i]);
  34. }
  35. return $strings;
  36. }
  37. /**
  38. * encrypt a single string for ResponseWare
  39. * @param $str the string to encrypt
  40. * @return string
  41. */
  42. function encryptResponseWareString($str) {
  43. if( ! TURNINGTECH_ENABLE_ENCRYPTION ) return $str;
  44. $crunch = new TurningTechEncryptionHelper();
  45. $crunch->key = base64_decode( 'iZRKTcYfw9G2DGrdymD23w==' );
  46. $crunch->iv = base64_decode( 'DvNdhsQOmHhMn6ZESNTTlw==' );
  47. $crunch->mode = MCRYPT_MODE_CBC;
  48. $crunch->dobase64 = false;
  49. $crunch->doPKCS5 = true;
  50. return $crunch->encryptString( $str );
  51. }
  52. /**
  53. * encrypt a list of strings for ResponseWare
  54. * @param $strings array
  55. * @return string array
  56. */
  57. function encryptResponseWareStrings($strings) {
  58. if( ! TURNINGTECH_ENABLE_ENCRYPTION ) return $strings;
  59. for($i= 0; $i<count($strings); $i++) {
  60. $strings[$i] = encryptResponseWareString($strings[$i]);
  61. }
  62. return $strings;
  63. }
  64. /**
  65. * decrypt a single string for Web Services
  66. * @param $str the string to decrypt
  67. * @return string
  68. */
  69. function decryptWebServicesString($str) {
  70. if( ! TURNINGTECH_ENABLE_DECRYPTION ) return $str;
  71. $crunch = new TurningTechEncryptionHelper();
  72. $crunch->key = base64_decode( 'Uepfjci/SJ7t+10kCtn2qA==' );
  73. $crunch->iv = $crunch->key;
  74. $crunch->mode = MCRYPT_MODE_ECB;
  75. return $crunch->decryptString( $str );
  76. }
  77. /**
  78. * decrypt a list of strings for Web Services
  79. * @param $strings array
  80. * @return string array
  81. */
  82. function decryptWebServicesStrings($strings) {
  83. if( ! TURNINGTECH_ENABLE_DECRYPTION ) return $strings;
  84. for($i= 0; $i<count($strings); $i++) {
  85. $strings[$i] = decryptWebServicesString($strings[$i]);
  86. }
  87. return $strings;
  88. }
  89. /**
  90. * encrypt a single string for Web Services
  91. * @param $str the string to encrypt
  92. * @return string
  93. */
  94. function encryptWebServicesString($str) {
  95. if( ! TURNINGTECH_ENABLE_ENCRYPTION ) return $str;
  96. $crunch = new TurningTechEncryptionHelper();
  97. $crunch->key = base64_decode( 'Uepfjci/SJ7t+10kCtn2qA==' );
  98. $crunch->iv = $crunch->key;
  99. $crunch->mode = MCRYPT_MODE_ECB;
  100. return $crunch->encryptString( $str );
  101. }
  102. /**
  103. * encrypt a list of strings for Web Services
  104. * @param $strings array
  105. * @return string array
  106. */
  107. function encryptWebServicesStrings($strings) {
  108. if( ! TURNINGTECH_ENABLE_ENCRYPTION ) return $strings;
  109. for($i= 0; $i<count($strings); $i++) {
  110. $strings[$i] = encryptWebServicesString($strings[$i]);
  111. }
  112. return $strings;
  113. }
  114. /***
  115. * utility class that handles AES encryption/encoding
  116. */
  117. class TurningTechEncryptionHelper {
  118. public $algorithm = MCRYPT_RIJNDAEL_128; // use MCRYPT_RIJNDAEL_128 for AES
  119. public $algorithm_directory = '';
  120. public $mode = MCRYPT_MODE_ECB;
  121. public $mode_directory = '';
  122. public $dobase64 = true;
  123. public $doPKCS5 = true;
  124. public $key = '';
  125. public $iv = ''; // NOTE: must be the same value for encrypt/decrypt
  126. const ENCRYPT = 1;
  127. const DECRYPT = 2;
  128. /**
  129. * decrypt a single string
  130. * @param $str the string to decrypt
  131. * @return string
  132. */
  133. public function decryptString($str) {
  134. if( ! TURNINGTECH_ENABLE_DECRYPTION ) return $str;
  135. return $this->processData( self::DECRYPT, $str );
  136. }
  137. /**
  138. * decrypt a list of strings
  139. * @param $strings array
  140. * @return string array
  141. */
  142. public function decryptStrings($strings) {
  143. if( ! TURNINGTECH_ENABLE_DECRYPTION ) return $strings;
  144. for($i= 0; $i<count($strings); $i++) {
  145. $strings[$i] = $this->decryptString($strings[$i]);
  146. }
  147. return $strings;
  148. }
  149. /**
  150. * encrypt a single string
  151. * @param $str the string to encrypt
  152. * @return string
  153. */
  154. public function encryptString($str) {
  155. if( ! TURNINGTECH_ENABLE_ENCRYPTION ) return $str;
  156. return $this->processData( self::ENCRYPT, $str );
  157. }
  158. /**
  159. * encrypt a list of strings
  160. * @param $strings array
  161. * @return string array
  162. */
  163. public function encryptStrings($strings) {
  164. if( ! TURNINGTECH_ENABLE_ENCRYPTION ) return $strings;
  165. for($i= 0; $i<count($strings); $i++) {
  166. $strings[$i] = $this->encryptString($strings[$i]);
  167. }
  168. return $strings;
  169. }
  170. /**
  171. * generic encrypt/decrypt logic
  172. * @param $direction pass in either self::ENCRYPT or self::DECRYPT
  173. * @param $str the data to encrypt/decrypt
  174. * @return string
  175. */
  176. protected function processData($direction, $str) {
  177. if( $direction != self::ENCRYPT && $direction != self::DECRYPT ) throw new TurningTechEncryptionHelperException( 'Unknown encryption request ' . $direction );
  178. $td = mcrypt_module_open( $this->algorithm, $this->algorithm_directory, $this->mode, $this->mode_directory );
  179. if( $td != false ) {
  180. if( $direction == self::ENCRYPT && $this->doPKCS5 ) $str = $this->padWithPKCS5( $str );
  181. if( $direction == self::DECRYPT && $this->dobase64 ) $str = base64_decode( $str );
  182. $ivsize = mcrypt_enc_get_iv_size( $td );
  183. if( $this->iv == '' ) $this->iv = mcrypt_create_iv( $ivsize ); // NOTE: must be the same value for encrypt/decrypt
  184. if( $ivsize != strlen( $this->iv ) ) throw new TurningTechEncryptionHelperException( 'size of given IV ' . strlen( $this->iv ) . ' does not match required size ' . $ivsize );
  185. $keysize = mcrypt_enc_get_key_size( $td );
  186. if( strlen( $this->key ) > $keysize ) throw new TurningTechEncryptionHelperException( 'size of key ' . strlen( $this->key ) . ' is greater than the maximum allowed size ' . $keysize );
  187. if( strlen( $this->key ) <= 0 ) throw new TurningTechEncryptionHelperException( 'size of key ' . strlen( $this->key ) . ' is too small' );
  188. $initstatus = mcrypt_generic_init( $td, $this->key, $this->iv );
  189. if( $initstatus === false || $initstatus < 0 ) throw new TurningTechEncryptionHelperException( 'mcrypt_generic_init() returned error code ' . $initstatus );
  190. if( $direction == self::ENCRYPT ) {
  191. $str = mcrypt_generic( $td, $str );
  192. } elseif( $direction == self::DECRYPT ) {
  193. $str = mdecrypt_generic( $td, $str );
  194. }
  195. if( ! mcrypt_generic_deinit( $td ) ) throw new TurningTechEncryptionHelperException( 'mcrypt_generic_deinit() returned FALSE' );
  196. //if( mcrypt_module_close( $td ) ) throw new EncryptionHelperException( 'mcrypt_module_close() returned FALSE' );
  197. mcrypt_module_close( $td ); // it returns false locally, for some unknown reason
  198. $td = false; // a pointer handling habit :)
  199. if( $direction == self::ENCRYPT && $this->dobase64 ) $str = base64_encode( $str );
  200. if( $direction == self::DECRYPT && $this->doPKCS5 ) $str = $this->unpadWithPKCS5( $str );
  201. } else {
  202. throw new TurningTechEncryptionHelperException( 'mcrypt_module_open() returned FALSE ' );
  203. }
  204. return $str;
  205. }
  206. /**
  207. * apply PKCS #5 padding to string
  208. * @param $s the string to pad
  209. * @return string
  210. */
  211. protected function padWithPKCS5( $s ) {
  212. $blocksize = mcrypt_get_block_size( $this->algorithm, $this->mode );
  213. $padsize = $blocksize - (strlen( $s ) % $blocksize);
  214. $s .= str_repeat( chr( $padsize ), $padsize );
  215. return $s;
  216. }
  217. /**
  218. * remove PKCS #5 padding from string
  219. * @param $s the string to de-pad
  220. * @return string
  221. */
  222. protected function unpadWithPKCS5( $s ) {
  223. $ssize = strlen( $s );
  224. $padsize = ord( $s[$ssize - 1] );
  225. if( $padsize <= $ssize && strspn( $s, chr( $padsize ), $ssize - $padsize ) == $padsize ) {
  226. $s = substr( $s, 0, -$padsize );
  227. }
  228. return $s;
  229. }
  230. }
  231. /**
  232. * Establish an exception namespace, add output to error_log()
  233. */
  234. class TurningTechEncryptionHelperException extends Exception {
  235. public function __tostring() {
  236. if( TURNINGTECH_ENABLE_ENCRYPTION_EXCEPTIONS_IN_ERROR_LOG ) error_log( $this->getMessage() );
  237. return parent::__tostring();
  238. }
  239. }
  240. ?>