* 所有相关信息仅技术学习调研,不公开任何侵犯公司价值信息,若有侵犯,请联系删除
可以获取到 ip port username password conntype
PHP
<?php namespace FatSmallTools; class NavicatPassword { protected $version = 0; protected $aesKey = 'libcckeylibcckey'; protected $aesIv = 'libcciv libcciv '; protected $blowString = '3DC5CA39'; protected $blowKey = null; protected $blowIv = null; public function __construct($version = 12) { $this->version = $version; $this->blowKey = sha1('3DC5CA39', true); $this->blowIv = hex2bin('d9c7c3c8870d64bd'); } public function encrypt($string) { $result = FALSE; switch ($this->version) { case 11: $result = $this->encryptEleven($string); break; case 12: $result = $this->encryptTwelve($string); break; default: break; } return $result; } protected function encryptEleven($string) { $round = intval(floor(strlen($string) / 8)); $leftLength = strlen($string) % 8; $result = ''; $currentVector = $this->blowIv; for ($i = 0; $i < $round; $i++) { $temp = $this->encryptBlock($this->xorBytes(substr($string, 8 * $i, 8), $currentVector)); $currentVector = $this->xorBytes($currentVector, $temp); $result .= $temp; } if ($leftLength) { $currentVector = $this->encryptBlock($currentVector); $result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector); } return strtoupper(bin2hex($result)); } protected function encryptBlock($block) { return openssl_encrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING); } protected function decryptBlock($block) { return openssl_decrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING); } protected function xorBytes($str1, $str2) { $result = ''; for ($i = 0; $i < strlen($str1); $i++) { $result .= chr(ord($str1[$i]) ^ ord($str2[$i])); } return $result; } protected function encryptTwelve($string) { $result = openssl_encrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv); return strtoupper(bin2hex($result)); } public function decrypt($string) { $result = FALSE; switch ($this->version) { case 11: $result = $this->decryptEleven($string); break; case 12: $result = $this->decryptTwelve($string); break; default: break; } return $result; } protected function decryptEleven($upperString) { $string = hex2bin(strtolower($upperString)); $round = intval(floor(strlen($string) / 8)); $leftLength = strlen($string) % 8; $result = ''; $currentVector = $this->blowIv; for ($i = 0; $i < $round; $i++) { $encryptedBlock = substr($string, 8 * $i, 8); $temp = $this->xorBytes($this->decryptBlock($encryptedBlock), $currentVector); $currentVector = $this->xorBytes($currentVector, $encryptedBlock); $result .= $temp; } if ($leftLength) { $currentVector = $this->encryptBlock($currentVector); $result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector); } return $result; } protected function decryptTwelve($upperString) { $string = hex2bin(strtolower($upperString)); return openssl_decrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv); } } //namespace FatSmallTools\Tests; use PHPUnit\Framework\TestCase; //use FatSmallTools\NavicatPassword; class NavicatPasswordTest { public function testHandleTwelve() { $navicatPassword = new NavicatPassword(12); $string = '123456'; $encrypted = $navicatPassword->encrypt($string); $this->assertEquals('833E4ABBC56C89041A9070F043641E3B', $encrypted); $decrypted = $navicatPassword->decrypt($encrypted); $this->assertEquals($string, $decrypted); $string = 'This is a test'; $encrypted = $navicatPassword->encrypt($string); $this->assertEquals('B75D320B6211468D63EB3B67C9E85933', $encrypted); $decrypted = $navicatPassword->decrypt($encrypted); $this->assertEquals($string, $decrypted); } public function testHandleEleven() { $navicatPassword = new NavicatPassword(11); $string = '123456'; $encrypted = $navicatPassword->encrypt($string); $this->assertEquals('15057D7BA390', $encrypted); $decrypted = $navicatPassword->decrypt($encrypted); $this->assertEquals($string, $decrypted); $string = 'This is a test'; $encrypted = $navicatPassword->encrypt($string); $this->assertEquals('0EA71F51DD37BFB60CCBA219BE3A', $encrypted); $decrypted = $navicatPassword->decrypt($encrypted); $this->assertEquals($string, $decrypted); } } //use FatSmallTools\NavicatPassword; //需要指定版本,11或12 $navicatPassword = new NavicatPassword(11); //$navicatPassword = new NavicatPassword(12); //加密 $encode = $navicatPassword->encrypt('123456'); // verstion 11 15057D7BA390, version 12 833E4ABBC56C89041A9070F043641E3B //解密 $decode = $navicatPassword->decrypt('15057D7BA390'); //$decode = $navicatPassword->decrypt('833E4ABBC56C89041A9070F043641E3B'); //$result = print_r(getArrayData(), true); // 获取函数返回值并转换成字符串形式 echo $decode; // 输出函数返回值
* 如果解出来是乱码需要切换版本
Python
#!/usr/bin/env python3 import sys from Crypto.Hash import SHA1 from Crypto.Cipher import AES, Blowfish from Crypto.Util import strxor, Padding class Navicat11Crypto: def __init__(self, Key = b'3DC5CA39'): self._Key = SHA1.new(Key).digest() self._Cipher = Blowfish.new(self._Key, Blowfish.MODE_ECB) self._IV = self._Cipher.encrypt(b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF') def EncryptString(self, s : str): if type(s) != str: raise TypeError('Parameter s must be a str.') else: plaintext = s.encode('ascii') ciphertext = b'' cv = self._IV full_round, left_length = divmod(len(plaintext), 8) for i in range(0, full_round * 8, 8): t = strxor.strxor(plaintext[i:i + 8], cv) t = self._Cipher.encrypt(t) cv = strxor.strxor(cv, t) ciphertext += t if left_length != 0: cv = self._Cipher.encrypt(cv) ciphertext += strxor.strxor(plaintext[8 * full_round:], cv[:left_length]) return ciphertext.hex().upper() def DecryptString(self, s : str): if type(s) != str: raise TypeError('Parameter s must be str.') else: plaintext = b'' ciphertext = bytes.fromhex(s) cv = self._IV full_round, left_length = divmod(len(ciphertext), 8) for i in range(0, full_round * 8, 8): t = self._Cipher.decrypt(ciphertext[i:i + 8]) t = strxor.strxor(t, cv) plaintext += t cv = strxor.strxor(cv, ciphertext[i:i + 8]) if left_length != 0: cv = self._Cipher.encrypt(cv) plaintext += strxor.strxor(ciphertext[8 * full_round:], cv[:left_length]) return plaintext.decode('ascii') class Navicat12Crypto(Navicat11Crypto): def __init__(self): super().__init__() def EncryptStringForNCX(self, s : str): cipher = AES.new(b'libcckeylibcckey', AES.MODE_CBC, iv = b'libcciv libcciv ') padded_plaintext = Padding.pad(s.encode('ascii'), AES.block_size, style = 'pkcs7') return cipher.encrypt(padded_plaintext).hex().upper() def DecryptStringForNCX(self, s : str): cipher = AES.new(b'libcckeylibcckey', AES.MODE_CBC, iv = b'libcciv libcciv ') padded_plaintext = cipher.decrypt(bytes.fromhex(s)) return Padding.unpad(padded_plaintext, AES.block_size, style = 'pkcs7').decode('ascii') if __name__ == '__main__': def Help(): print('Usage:') print(' NavicatCrypto.py <enc|dec> [-ncx] <plaintext|ciphertext>') print('') print(' <enc|dec> "enc" for encryption, "dec" for decryption.') print(' This parameter must be specified.') print('') print(' [-ncx] Indicate that plaintext/ciphertext is') print(' prepared for/exported from NCX file.') print(' This parameter is optional.') print('') print(' <plaintext|ciphertext> Plaintext string or ciphertext string.') print(' NOTICE: Ciphertext string must be a hex string.') print(' This parameter must be specified.') print('') def Main(argc : int, argv : list): if argc == 3: if argv[1].lower() == 'enc': print(Navicat11Crypto().EncryptString(argv[2])) elif argv[1].lower() == 'dec': print(Navicat11Crypto().DecryptString(argv[2])) else: Help() return -1 elif argc == 4: if argv[1].lower() == 'enc' and argv[2].lower() == '-ncx': print(Navicat12Crypto().EncryptStringForNCX(argv[3])) elif argv[1].lower() == 'dec' and argv[2].lower() == '-ncx': print(Navicat12Crypto().DecryptStringForNCX(argv[3])) else: Help() return -1 else: Help() return 0 exit(Main(len(sys.argv), sys.argv))
* 如果是 .ncx 文件需要编译调用 ncx 函数方法
* 所有相关信息仅技术学习调研,不公开任何侵犯公司价值信息,若有侵犯,请联系删除