前言
-
相信你会遇到使用navicat忘记已连接数据密码的问题吧!实在是,密码太多容易忘记!!!
-
感谢大佬as_dmy的文章如何查看navicat已连接数据库密码,然后才有了此文!
-
1.0版本需要手动查看导出的connections.ncx文件中的加密密码值,然后解密
-
2.0版本直接选择文件【支持一个数据库密码的导出文件】,然后解密
-
源码相关资源免费获取!请查看工具获取章节内容!
-
有愿意研究源码的可以看看
源码
1.0 版本源码
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.nio.charset.StandardCharsets;public class NavicatPasswordGUI {private JFrame frame;private JComboBox<String> versionComboBox;private JTextField originalPasswordTextField;private JTextField encryptedPasswordTextField;private JTextField decryptedPasswordTextField;private String blowKey = "3DC5CA39";private byte[] blowIv = hexStringToByteArray("d9c7c3c8870d64bd");private String aesKey = "libcckeylibcckey";private String aesIv = "libcciv libcciv ";public NavicatPasswordGUI() {frame = new JFrame("Navicat Password Encryption/Decryption");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400, 250);frame.setLayout(new GridLayout(5, 2));JLabel versionLabel = new JLabel("navicat Version:");versionComboBox = new JComboBox<>(new String[]{"11", "12"});frame.add(versionLabel);frame.add(versionComboBox);JLabel originalPasswordLabel = new JLabel("Original Password:");originalPasswordTextField = new JTextField();frame.add(originalPasswordLabel);frame.add(originalPasswordTextField);JLabel encryptedPasswordLabel = new JLabel("Encrypted Password:");encryptedPasswordTextField = new JTextField();encryptedPasswordTextField.setEditable(false);frame.add(encryptedPasswordLabel);frame.add(encryptedPasswordTextField);JLabel decryptedPasswordLabel = new JLabel("Decrypted Password:");decryptedPasswordTextField = new JTextField();frame.add(decryptedPasswordLabel);frame.add(decryptedPasswordTextField);JButton encryptButton = new JButton("Encrypt");frame.add(encryptButton);JButton decryptButton = new JButton("Decrypt");frame.add(decryptButton);encryptButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {int version = Integer.parseInt((String) versionComboBox.getSelectedItem());String originalPassword = originalPasswordTextField.getText();NavicatPassword navicatPassword = new NavicatPassword(version);String encryptedPassword = navicatPassword.encrypt(originalPassword);encryptedPasswordTextField.setText(encryptedPassword);} catch (Exception ex) {JOptionPane.showMessageDialog(frame, "Error: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);}}});decryptButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {int version = Integer.parseInt((String) versionComboBox.getSelectedItem());String encryptedPassword = decryptedPasswordTextField.getText();NavicatPassword navicatPassword = new NavicatPassword(version);String decryptedPassword = navicatPassword.decrypt(encryptedPassword);originalPasswordTextField.setText(decryptedPassword);} catch (Exception ex) {JOptionPane.showMessageDialog(frame, "Error: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);}}});frame.setVisible(true);}public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {new NavicatPasswordGUI();}});}private byte[] hexStringToByteArray(String s) {int len = s.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));}return data;}
}class NavicatPassword {private int version;private String blowKey = "3DC5CA39";private byte[] blowIv = hexStringToByteArray("d9c7c3c8870d64bd");private String aesKey = "libcckeylibcckey";private String aesIv = "libcciv libcciv ";public NavicatPassword(int version) {this.version = version;}public String encrypt(String input) throws Exception {switch (version) {case 11:return encryptEleven(input);case 12:return encryptTwelve(input);default:throw new IllegalArgumentException("Unsupported version: " + version);}}public String decrypt(String input) throws Exception {switch (version) {case 11:return decryptEleven(input);case 12:return decryptTwelve(input);default:throw new IllegalArgumentException("Unsupported version: " + version);}}private String encryptEleven(String input) throws Exception {int round = input.length() / 8;int leftLength = input.length() % 8;StringBuilder result = new StringBuilder();byte[] currentVector = blowIv.clone();for (int i = 0; i < round; i++) {byte[] temp = encryptBlock(xorBytes(input.getBytes(StandardCharsets.UTF_8), currentVector));currentVector = xorBytes(currentVector, temp);result.append(byteArrayToHexString(temp));}if (leftLength != 0) {currentVector = encryptBlock(currentVector);result.append(byteArrayToHexString(xorBytes(input.substring(8 * round).getBytes(StandardCharsets.UTF_8), currentVector)));}return result.toString().toUpperCase();}private byte[] encryptBlock(byte[] block) throws Exception {Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");SecretKeySpec secretKeySpec = new SecretKeySpec(blowKey.getBytes(StandardCharsets.UTF_8), "Blowfish");cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);return cipher.doFinal(block);}private byte[] decryptBlock(byte[] block) throws Exception {Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");SecretKeySpec secretKeySpec = new SecretKeySpec(blowKey.getBytes(StandardCharsets.UTF_8), "Blowfish");cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);return cipher.doFinal(block);}private byte[] xorBytes(byte[] bytes1, byte[] bytes2) {byte[] result = new byte[bytes1.length];for (int i = 0; i < bytes1.length; i++) {result[i] = (byte) (bytes1[i] ^ bytes2[i]);}return result;}private String decryptEleven(String upperString) throws Exception {String input = upperString.toLowerCase();int round = input.length() / 16;int leftLength = input.length() % 16;StringBuilder result = new StringBuilder();byte[] currentVector = blowIv.clone();for (int i = 0; i < round; i++) {byte[] encryptedBlock = hexStringToByteArray(input.substring(16 * i, 16 * (i + 1)));byte[] temp = xorBytes(decryptBlock(encryptedBlock), currentVector);currentVector = xorBytes(currentVector, encryptedBlock);result.append(byteArrayToHexString(temp));}if (leftLength != 0) {currentVector = encryptBlock(currentVector);result.append(byteArrayToHexString(xorBytes(input.substring(16 * round).getBytes(StandardCharsets.UTF_8), currentVector)));}return new String(hexStringToByteArray(result.toString()), StandardCharsets.UTF_8);}private String encryptTwelve(String input) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), "AES");IvParameterSpec ivSpec = new IvParameterSpec(aesIv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);byte[] encrypted = cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));return byteArrayToHexString(encrypted).toUpperCase();}private String decryptTwelve(String upperString) throws Exception {byte[] input = hexStringToByteArray(upperString.toLowerCase());Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), "AES");IvParameterSpec ivSpec = new IvParameterSpec(aesIv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);byte[] decrypted = cipher.doFinal(input);return new String(decrypted, StandardCharsets.UTF_8);}private byte[] hexStringToByteArray(String s) {int len = s.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));}return data;}private String byteArrayToHexString(byte[] bytes) {StringBuilder result = new StringBuilder();for (byte b : bytes) {result.append(String.format("%02X", b));}return result.toString();}
}
2.0 版本源码
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;public class NavicatPasswordGUI {private final JFrame frame;private final JComboBox<String> versionComboBox;private final JTextField originalPasswordTextField;private final JTextField encryptedPasswordTextField;private final JTextField decryptedPasswordTextField;private final JButton selectFileButton;private final String blowKey = "3DC5CA39";private final byte[] blowIv = hexStringToByteArray("d9c7c3c8870d64bd");private final String aesKey = "libcckeylibcckey";private final String aesIv = "libcciv libcciv ";public NavicatPasswordGUI() {frame = new JFrame("Navicat Password Encryption/Decryption");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400, 250);frame.setLayout(new GridLayout(6, 2));JLabel versionLabel = new JLabel("navicat Version:");versionComboBox = new JComboBox<>(new String[]{"11", "12"});frame.add(versionLabel);frame.add(versionComboBox);JLabel originalPasswordLabel = new JLabel("Original Password:");originalPasswordTextField = new JTextField();frame.add(originalPasswordLabel);frame.add(originalPasswordTextField);JLabel encryptedPasswordLabel = new JLabel("Encrypted Password:");encryptedPasswordTextField = new JTextField();encryptedPasswordTextField.setEditable(false);frame.add(encryptedPasswordLabel);frame.add(encryptedPasswordTextField);JLabel decryptedPasswordLabel = new JLabel("Decrypted Password:");decryptedPasswordTextField = new JTextField();decryptedPasswordTextField.setEditable(false);frame.add(decryptedPasswordLabel);frame.add(decryptedPasswordTextField);selectFileButton = new JButton("Select File");frame.add(selectFileButton);JButton encryptButton = new JButton("Encrypt");frame.add(encryptButton);JButton decryptButton = new JButton("Decrypt");frame.add(decryptButton);selectFileButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {JFileChooser fileChooser = new JFileChooser();int returnValue = fileChooser.showOpenDialog(null);if (returnValue == JFileChooser.APPROVE_OPTION) {File selectedFile = fileChooser.getSelectedFile();try {// 使用DOM解析XML文件DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(selectedFile);// 查找密码字段NodeList connectionsList = doc.getElementsByTagName("Connection");if (connectionsList.getLength() > 0) {Element connectionElement = (Element) connectionsList.item(0);String password = connectionElement.getAttribute("Password");decryptedPasswordTextField.setText(password);} else {JOptionPane.showMessageDialog(frame, "No Connection element found in the XML file.", "Error", JOptionPane.ERROR_MESSAGE);}} catch (ParserConfigurationException | IOException | org.xml.sax.SAXException ex) {JOptionPane.showMessageDialog(frame, "Error reading XML file: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);}}}});encryptButton.addActionListener(e -> {try {int version = Integer.parseInt((String) versionComboBox.getSelectedItem());String originalPassword = originalPasswordTextField.getText();NavicatPassword navicatPassword = new NavicatPassword(version);String encryptedPassword = navicatPassword.encrypt(originalPassword);encryptedPasswordTextField.setText(encryptedPassword);} catch (Exception ex) {JOptionPane.showMessageDialog(frame, "Error: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);}});decryptButton.addActionListener(e -> {try {int version = Integer.parseInt((String) versionComboBox.getSelectedItem());String encryptedPassword = decryptedPasswordTextField.getText();NavicatPassword navicatPassword = new NavicatPassword(version);String decryptedPassword = navicatPassword.decrypt(encryptedPassword);originalPasswordTextField.setText(decryptedPassword);} catch (Exception ex) {JOptionPane.showMessageDialog(frame, "Error: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);}});frame.setVisible(true);}public static void main(String[] args) {SwingUtilities.invokeLater(() -> new NavicatPasswordGUI());}private byte[] hexStringToByteArray(String s) {int len = s.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));}return data;}
}class NavicatPassword {private final int version;private final String blowKey = "3DC5CA39";private final byte[] blowIv = hexStringToByteArray("d9c7c3c8870d64bd");private final String aesKey = "libcckeylibcckey";private final String aesIv = "libcciv libcciv ";public NavicatPassword(int version) {this.version = version;}public String encrypt(String input) throws Exception {switch (version) {case 11:return encryptEleven(input);case 12:return encryptTwelve(input);default:throw new IllegalArgumentException("Unsupported version: " + version);}}public String decrypt(String input) throws Exception {switch (version) {case 11:return decryptEleven(input);case 12:return decryptTwelve(input);default:throw new IllegalArgumentException("Unsupported version: " + version);}}private String encryptEleven(String input) throws Exception {int round = input.length() / 8;int leftLength = input.length() % 8;StringBuilder result = new StringBuilder();byte[] currentVector = blowIv.clone();for (int i = 0; i < round; i++) {byte[] temp = encryptBlock(xorBytes(input.getBytes(StandardCharsets.UTF_8), currentVector));currentVector = xorBytes(currentVector, temp);result.append(byteArrayToHexString(temp));}if (leftLength != 0) {currentVector = encryptBlock(currentVector);result.append(byteArrayToHexString(xorBytes(input.substring(8 * round).getBytes(StandardCharsets.UTF_8), currentVector)));}return result.toString().toUpperCase();}private byte[] encryptBlock(byte[] block) throws Exception {Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");SecretKeySpec secretKeySpec = new SecretKeySpec(blowKey.getBytes(StandardCharsets.UTF_8), "Blowfish");cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);return cipher.doFinal(block);}private byte[] decryptBlock(byte[] block) throws Exception {Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");SecretKeySpec secretKeySpec = new SecretKeySpec(blowKey.getBytes(StandardCharsets.UTF_8), "Blowfish");cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);return cipher.doFinal(block);}private byte[] xorBytes(byte[] bytes1, byte[] bytes2) {byte[] result = new byte[bytes1.length];for (int i = 0; i < bytes1.length; i++) {result[i] = (byte) (bytes1[i] ^ bytes2[i]);}return result;}private String decryptEleven(String upperString) throws Exception {String input = upperString.toLowerCase();int round = input.length() / 16;int leftLength = input.length() % 16;StringBuilder result = new StringBuilder();byte[] currentVector = blowIv.clone();for (int i = 0; i < round; i++) {byte[] encryptedBlock = hexStringToByteArray(input.substring(16 * i, 16 * (i + 1)));byte[] temp = xorBytes(decryptBlock(encryptedBlock), currentVector);currentVector = xorBytes(currentVector, encryptedBlock);result.append(byteArrayToHexString(temp));}if (leftLength != 0) {currentVector = encryptBlock(currentVector);result.append(byteArrayToHexString(xorBytes(input.substring(16 * round).getBytes(StandardCharsets.UTF_8), currentVector)));}return new String(hexStringToByteArray(result.toString()), StandardCharsets.UTF_8);}private String encryptTwelve(String input) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), "AES");IvParameterSpec ivSpec = new IvParameterSpec(aesIv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);byte[] encrypted = cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));return byteArrayToHexString(encrypted).toUpperCase();}private String decryptTwelve(String upperString) throws Exception {byte[] input = hexStringToByteArray(upperString.toLowerCase());Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), "AES");IvParameterSpec ivSpec = new IvParameterSpec(aesIv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);byte[] decrypted = cipher.doFinal(input);return new String(decrypted, StandardCharsets.UTF_8);}private byte[] hexStringToByteArray(String s) {int len = s.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));}return data;}private String byteArrayToHexString(byte[] bytes) {StringBuilder result = new StringBuilder();for (byte b : bytes) {result.append(String.format("%02X", b));}return result.toString();}
}
打包步骤
-
编写并保存上述Java代码为一个.java文件
-
打开终端或命令提示符,进入包含.java文件的目录。
-
使用Java编译器(javac)编译Java类文件。例如:
javac NavicatPasswordGUI.java
-
创建一个包含
MANIFEST.MF
文件的目录,其中包含以下内容:Manifest-Version: 1.0 Main-Class: NavicatPasswordGUI
-
打包成JAR文件,使用以下命令:
- 创建一个名为
NavicatPasswordGUI.jar
的JAR文件,其中包含Java类以及MANIFEST文件。
jar cfm NavicatPasswordGUI.jar MANIFEST.MF *.class
- 创建一个名为
-
运行JAR文件,或者双击:
java -jar NavicatPasswordGUI.jar
工具获取
- 相关资源获取 NavicatPassword Decryp tools.zip
操作方法
导出navicat数据库连接信息
-
打开navicat,点击文件➡导出连接
-
勾选需要导出的连接,注意,勾选“导出密码”
使用工具
- 相信使用navicat的小伙伴,电脑一定配置了java环境,如果有例外,请自行百度,安装java环境!
工具1.0使用方法
- 打开connections.ncx复制password内容
- 双击打开1.0版本目录下jar包 ,选择navicate版本,粘贴复制的密码内容,点击解密即可
- Navicat 15和Navicat 16请选择版本为12,其他请尝试不同版本的的解密!
- 如果版本选择错误,会出现乱码的结果,请多多尝试
工具2.0 使用方法
- 运行工具,选择导出的连接文件,点击解密即可