TeaHander.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Mead
  5. * Date: 2019/9/25
  6. * Time: 6:12 PM
  7. */
  8. namespace App\Handlers;
  9. class TeaHander
  10. {
  11. private static $op = 0xffffffff;
  12. public static function encrypt($v, $k)
  13. {
  14. $vl = strlen($v);
  15. $filln = (8 - ($vl + 2)) % 8 + 2;
  16. if ($filln >= 2 && $filln < 9) {
  17. } else {
  18. $filln += 8;
  19. }
  20. $fills = '';
  21. for ($i = 0; $i < $filln; $i++) {
  22. $fills .= chr(rand(0, 0xff));
  23. }
  24. $v = chr(($filln - 2) | 0xF8) . $fills . $v;
  25. $tmp_l = strlen($v) + 7;
  26. $v = pack("a{$tmp_l}", $v);
  27. $tr = pack("a8", '');
  28. $to = pack("a8", '');
  29. $r = '';
  30. $o = pack("a8", '');
  31. for ($i = 0; $i < strlen($v); $i = $i + 8) {
  32. $o = self::_xor(substr($v, $i, 8), $tr);
  33. $tr = self::_xor(self::block_encrypt($o, $k), $to);
  34. $to = $o;
  35. $r .= $tr;
  36. }
  37. return $r;
  38. }
  39. public static function decrypt($v, $k)
  40. {
  41. $l = strlen($v);
  42. $prePlain = self::block_decrypt($v, $k);
  43. $pos = (ord($prePlain[0]) & 0x07) + 2;
  44. $r = $prePlain;
  45. $preCrypt = substr($v, 0, 8);
  46. for ($i = 8; $i < $l; $i = $i + 8) {
  47. $x = self::_xor(
  48. self::block_decrypt(self::_xor(
  49. substr($v, $i, $i + 8), $prePlain),
  50. $k),
  51. $preCrypt);
  52. $prePlain = self::_xor($x, $preCrypt);
  53. $preCrypt = substr($v, $i, $i + 8);
  54. $r .= $x;
  55. }
  56. if (substr($r, -7) != pack("a7", '')) {
  57. return "";
  58. }
  59. return substr($r, $pos + 1, -7);
  60. }
  61. private static function _xor($a, $b)
  62. {
  63. $a = self::_str2long($a);
  64. $a1 = $a[0];
  65. $a2 = $a[1];
  66. $b = self::_str2long($b);
  67. $b1 = $b[0];
  68. $b2 = $b[1];
  69. return self::_long2str(($a1 ^ $b1) & self::$op) .
  70. self::_long2str(($a2 ^ $b2) & self::$op);
  71. }
  72. public static function block_encrypt($v, $k)
  73. {
  74. $s = 0;
  75. $delta = 0x9e3779b9;
  76. $n = 16;
  77. $k = self::_str2long($k);
  78. $v = self::_str2long($v);
  79. $z = $v[1];
  80. $y = $v[0];
  81. /* start cycle */
  82. for ($i = 0; $i < $n; $i++) {
  83. $s += $delta;
  84. $y += (self::$op & ($z << 4)) + $k[0] ^ $z + $s ^ (self::$op & ($z >> 5)) + $k[1];
  85. $y &= self::$op;
  86. $z += (self::$op & ($y << 4)) + $k[2] ^ $y + $s ^ (self::$op & ($y >> 5)) + $k[3];
  87. $z &= self::$op;
  88. }
  89. /* end cycle */
  90. return self::_long2str($y) . self::_long2str($z);
  91. }
  92. public static function block_decrypt($v, $k)
  93. {
  94. $delta = 0x9e3779b9;
  95. $s = ($delta << 4) & self::$op;
  96. #$s=0xC6EF3720;
  97. $n = 16;
  98. $v = self::_str2long($v);
  99. $k = self::_str2long($k);
  100. $y = $v[0];
  101. $z = $v[1];
  102. $a = $k[0];
  103. $b = $k[1];
  104. $c = $k[2];
  105. $d = $k[3];
  106. for ($i = 0; $i < $n; $i++) {
  107. $z -= (($y << 4) + $c) ^ ($y + $s) ^ (($y >> 5) + $d);
  108. $z &= self::$op;
  109. $y -= (($z << 4) + $a) ^ ($z + $s) ^ (($z >> 5) + $b);
  110. $y &= self::$op;
  111. $s -= $delta;
  112. $s &= self::$op;
  113. }
  114. return self::_long2str($y) . self::_long2str($z);
  115. }
  116. private static function _str2long($data)
  117. {
  118. $n = strlen($data);
  119. $tmp = unpack('N*', $data);
  120. $data_long = array();
  121. $j = 0;
  122. foreach ($tmp as $value) {
  123. $data_long[$j++] = $value;
  124. //if ($j >= 4) break;
  125. }
  126. return $data_long;
  127. }
  128. private static function _long2str($l)
  129. {
  130. return pack('N', $l);
  131. }
  132. public static function base64_url_encode($input)
  133. {
  134. return strtr(base64_encode($input), '+/=', '*-_');
  135. }
  136. public static function base64_url_decode($input)
  137. {
  138. return base64_decode(strtr($input, '*-_', '+/='));
  139. }
  140. public static function test()
  141. {
  142. $v = 'a';
  143. $k = '13404B5427A13C45E69BF78147E748D8';
  144. $data = self::encrypt($v, pack("H*", $k));
  145. $data = self::decrypt($data, pack("H*", $k));
  146. var_dump($data);
  147. $v = '008022a6785ec57392824936e439cd97' .
  148. '1d740c2ac0ca0d94e8c258aa2da8498a' .
  149. '0576c330828534efad26ca206eef39c3' .
  150. '994ca5265c719ef3289487893d2ef4e6' .
  151. 'ac72f35adfa3b02ab701673472bb6c88' .
  152. 'ba871b7bfe3bbe6f17c23b88d5a77e44' .
  153. '4b828456634aba70a3f36eb6763c51ca' .
  154. '5268ef461f20c73d45b71976a7bf347a' .
  155. 'd75b00000000a9884e910004214b4650';
  156. $data = self::encrypt($v, pack("H*", $k));
  157. $data = self::decrypt($data, pack("H*", $k));
  158. var_dump($data);
  159. $v = '008022a6785ec57392824936e439cd97' .
  160. '1d740c2ac0ca0d94e8c258aa2da8498a' .
  161. '0576c330828534efad26ca206eef39c3' .
  162. '994ca5265c719ef3289487893d2ef4e6' .
  163. 'ac72f35adfa3b02ab701673472bb6c88' .
  164. 'ba871b7bfe3bbe6f17c23b88d5a77e44' .
  165. '4b828456634aba70a3f36eb6763c51ca' .
  166. '5268ef461f20c73d45b71976a7bf347a' .
  167. 'd75b00000000a9884e910004214b4650';
  168. $data = self::encrypt(pack("H*", $v), pack("H*", $k));
  169. $data = self::decrypt($data, pack("H*", $k));
  170. var_dump(bin2hex($data));
  171. var_dump(self::decrypt('ec6d3c4a5deb1919e456a3c73c860a65a0ce9e4b', pack("H*", 'FB0E689B7A91AF66')));
  172. }
  173. }