openSRS_crypt.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. namespace DNSManager\opensrs;
  3. class openSRS_crypt {
  4. var $known_ciphers = array (
  5. 'DES' => MCRYPT_DES,
  6. 'BLOWFISH' => MCRYPT_BLOWFISH,
  7. 'BLOWFISH-COMPAT' => MCRYPT_BLOWFISH_COMPAT,
  8. );
  9. var $cipher; // used cipher - @var string
  10. var $TD; // crypt resource, for 2.4.x @var string
  11. var $deinit_function; // crypt deinit function, for backwards compatability - @var string
  12. var $blocksize; // blocksize of cipher - @var string
  13. var $keysize; // keysize of cipher - @var int
  14. var $keyhash; // mangled key - @var string
  15. var $rand_source = MCRYPT_RAND; // - source type of the initialization vector for creation - possible types are MCRYPT_RAND or MCRYPT_DEV_URANDOM or MCRYPT_DEV_RANDOM - @var int
  16. var $header_spec = 'RandomIV'; // - header - @var string
  17. var $_last_clear; // - debugging - @var string
  18. var $_last_crypt; // - debugging - @var string
  19. function __construct ($key, $cipher='DES') {
  20. if (!extension_loaded('mcrypt')) trigger_error ("oSRS Error - mcrypt module is not compiled into PHP", E_USER_ERROR);
  21. if (!function_exists('mcrypt_module_open')) trigger_error ("oSRS Error - libmcrypt version insufficient", E_USER_ERROR);
  22. if (function_exists('mcrypt_generic_deinit')) {
  23. $this->deinit_function = 'mcrypt_generic_deinit';
  24. } else if (function_exists('mcrypt_generic_end')) {
  25. $this->deinit_function = 'mcrypt_generic_end';
  26. } else {
  27. trigger_error ("oSRS Error - PHP version insufficient", E_USER_ERROR);
  28. }
  29. srand ((double)microtime()*1000000);
  30. $this->header_spec = 'RandomIV';
  31. if (!$key) trigger_error ("oSRS Error - no key specified", E_USER_ERROR);
  32. $cipher = strtoupper($cipher); // check for cipher
  33. if (!isset($this->known_ciphers[$cipher])) trigger_error ("oSRS Error - unknown cipher - ". $cipher, E_USER_ERROR);
  34. $this->cipher = $this->known_ciphers[$cipher];
  35. // initialize cipher
  36. $this->TD = mcrypt_module_open ($this->cipher, '', 'ecb', '');
  37. $this->blocksize = mcrypt_enc_get_block_size($this->TD);
  38. $this->keysize = mcrypt_enc_get_key_size($this->TD);
  39. // mangle key with MD5
  40. $this->keyhash = $this->_md5perl($key);
  41. while( strlen($this->keyhash) < $this->keysize ) {
  42. $this->keyhash .= $this->_md5perl($this->keyhash);
  43. }
  44. $this->key = substr($this->keyhash, 0, $this->keysize);
  45. return true;
  46. }
  47. // - Destructor
  48. function __destruct () {
  49. @mcrypt_module_close($this->TD);
  50. }
  51. function encrypt($clear) {
  52. $this->last_clear = $clear;
  53. $iv = mcrypt_create_iv($this->blocksize, $this->rand_source); /* new IV for each message */
  54. $crypt = $this->header_spec . $iv; /* create the message header */
  55. $padsize = $this->blocksize - (strlen($clear) % $this->blocksize); /* pad the cleartext */
  56. $clear .= str_repeat(pack ('C*', $padsize), $padsize);
  57. // do the encryption
  58. $start = 0;
  59. while ( $block = substr($clear, $start, $this->blocksize) ) {
  60. $start += $this->blocksize;
  61. if (mcrypt_generic_init($this->TD, $this->key, $iv) < 0 ) trigger_error ("oSRS Error - mcrypt_generic_init failed", E_USER_ERROR);
  62. $cblock = mcrypt_generic($this->TD, $iv^$block );
  63. $iv = $cblock;
  64. $crypt .= $cblock;
  65. call_user_func($this->deinit_function, $this->TD);
  66. }
  67. $this->last_crypt = $crypt;
  68. return $crypt;
  69. }
  70. function decrypt($crypt) {
  71. $this->last_crypt = $crypt;
  72. $iv_offset = strlen($this->header_spec); /* get the IV from the message header */
  73. $header = substr($crypt, 0, $iv_offset);
  74. $iv = substr ($crypt, $iv_offset, $this->blocksize);
  75. if ( $header != $this->header_spec ) trigger_error ("oSRS Error - no initialization vector", E_USER_ERROR);
  76. $crypt = substr($crypt, $iv_offset+$this->blocksize);
  77. /* decrypt the message */
  78. $start = 0;
  79. $clear = '';
  80. while ( $cblock = substr($crypt, $start, $this->blocksize) ) {
  81. $start += $this->blocksize;
  82. if (mcrypt_generic_init($this->TD, $this->key, $iv) < 0 ) trigger_error ("oSRS Error - mcrypt_generic_init failed", E_USER_ERROR);
  83. $block = $iv ^ mdecrypt_generic($this->TD, $cblock);
  84. $iv = $cblock;
  85. $clear .= $block;
  86. call_user_func($this->deinit_function, $this->TD);
  87. }
  88. /* remove the padding from the end of the cleartext */
  89. $padsize = ord(substr($clear, -1));
  90. $clear = substr($clear, 0, -$padsize);
  91. $this->last_clear = $clear;
  92. return $clear;
  93. }
  94. function _md5perl($string) {
  95. return pack('H*', md5($string));
  96. }
  97. }