fork download
  1. <?php
  2. class NavicatPassword
  3. {
  4. protected $version = 0;
  5. protected $aesKey = 'libcckeylibcckey';
  6. protected $aesIv = 'libcciv libcciv ';
  7. protected $blowString = '3DC5CA39';
  8. protected $blowKey = null;
  9. protected $blowIv = null;
  10.  
  11. public function __construct($version = 12)
  12. {
  13. $this->version = $version;
  14. $this->blowKey = sha1('3DC5CA39', true);
  15. $this->blowIv = hex2bin('d9c7c3c8870d64bd');
  16. }
  17.  
  18. public function encrypt($string)
  19. {
  20. $result = FALSE;
  21. switch ($this->version) {
  22. case 11:
  23. $result = $this->encryptEleven($string);
  24. break;
  25. case 12:
  26. $result = $this->encryptTwelve($string);
  27. break;
  28. default:
  29. break;
  30. }
  31.  
  32. return $result;
  33. }
  34.  
  35. protected function encryptEleven($string)
  36. {
  37. $round = intval(floor(strlen($string) / 8));
  38. $leftLength = strlen($string) % 8;
  39. $result = '';
  40. $currentVector = $this->blowIv;
  41.  
  42. for ($i = 0; $i < $round; $i++) {
  43. $temp = $this->encryptBlock($this->xorBytes(substr($string, 8 * $i, 8), $currentVector));
  44. $currentVector = $this->xorBytes($currentVector, $temp);
  45. $result .= $temp;
  46. }
  47.  
  48. if ($leftLength) {
  49. $currentVector = $this->encryptBlock($currentVector);
  50. $result .= $this->xorBytes(substr($string, 8 * $round), $currentVector);
  51. }
  52.  
  53. return strtoupper(bin2hex($result));
  54. }
  55.  
  56. protected function encryptBlock($block)
  57. {
  58. return openssl_encrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING);
  59. }
  60.  
  61. protected function decryptBlock($block)
  62. {
  63. return openssl_decrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING);
  64. }
  65.  
  66. protected function xorBytes($str1, $str2)
  67. {
  68. $result = '';
  69. for ($i = 0; $i < strlen($str1); $i++) {
  70. $result .= chr(ord($str1[$i]) ^ ord($str2[$i]));
  71. }
  72.  
  73. return $result;
  74. }
  75.  
  76. public function decrypt($string)
  77. {
  78. $result = FALSE;
  79. switch ($this->version) {
  80. case 11:
  81. $result = $this->decryptEleven($string);
  82. break;
  83. case 12:
  84. $result = $this->decryptTwelve($string);
  85. break;
  86. default:
  87. break;
  88. }
  89.  
  90. return $result;
  91. }
  92.  
  93. protected function decryptEleven($upperString)
  94. {
  95. $string = hex2bin(strtolower($upperString));
  96.  
  97. $round = intval(floor(strlen($string) / 8));
  98. $leftLength = strlen($string) % 8;
  99. $result = '';
  100. $currentVector = $this->blowIv;
  101.  
  102. for ($i = 0; $i < $round; $i++) {
  103. $encryptedBlock = substr($string, 8 * $i, 8);
  104. $temp = $this->xorBytes($this->decryptBlock($encryptedBlock), $currentVector);
  105. $currentVector = $this->xorBytes($currentVector, $encryptedBlock);
  106. $result .= $temp;
  107. }
  108.  
  109. if ($leftLength) {
  110. $currentVector = $this->encryptBlock($currentVector);
  111. $result .= $this->xorBytes(substr($string, 8 * $round), $currentVector);
  112. }
  113.  
  114. return $result;
  115. }
  116.  
  117. protected function encryptTwelve($string)
  118. {
  119. $result = openssl_encrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv);
  120. return strtoupper(bin2hex($result));
  121. }
  122.  
  123. protected function decryptTwelve($upperString)
  124. {
  125. $string = hex2bin(strtolower($upperString));
  126. return openssl_decrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv);
  127. }
  128. }
  129.  
  130. // 使用示例
  131. $navicatPassword = new NavicatPassword(12);
  132. $encryptedHex = 'B744013C755BBCE9B4F034329224';
  133. $decryptedPassword = $navicatPassword->decrypt($encryptedHex);
  134. echo "解密后的密码: ". $decryptedPassword. PHP_EOL;
  135. ?>
Success #stdin #stdout 0.03s 25832KB
stdin
Standard input is empty
stdout
解密后的密码: