Navicat15 /16 已连接数据库密码解密

前言

  • 相信你会遇到使用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() {
            @Override
            public 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() {
            @Override
            public 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() {
            @Override
            public 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() {
            @Override
            public 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();
    }
}

打包步骤

  1. 编写并保存上述Java代码为一个.java文件

  2. 打开终端或命令提示符,进入包含.java文件的目录。

  3. 使用Java编译器(javac)编译Java类文件。例如:

    javac NavicatPasswordGUI.java
    

在这里插入图片描述

  1. 创建一个包含MANIFEST.MF文件的目录,其中包含以下内容:

    Manifest-Version: 1.0
    Main-Class: NavicatPasswordGUI
    
  2. 打包成JAR文件,使用以下命令:

    • 创建一个名为NavicatPasswordGUI.jar的JAR文件,其中包含Java类以及MANIFEST文件。
    jar cfm NavicatPasswordGUI.jar MANIFEST.MF *.class
    
  3. 运行JAR文件,或者双击:

    java -jar NavicatPasswordGUI.jar
    

在这里插入图片描述

工具获取

操作方法

导出navicat数据库连接信息

  1. 打开navicat,点击文件➡导出连接
    在这里插入图片描述

  2. 勾选需要导出的连接,注意,勾选“导出密码”
    在这里插入图片描述

使用工具

  • 相信使用navicat的小伙伴,电脑一定配置了java环境,如果有例外,请自行百度,安装java环境!

工具1.0使用方法

  1. 打开connections.ncx复制password内容
    在这里插入图片描述
  2. 双击打开1.0版本目录下jar包 ,选择navicate版本,粘贴复制的密码内容,点击解密即可
    在这里插入图片描述
  • Navicat 15和Navicat 16请选择版本为12,其他请尝试不同版本的的解密!
  • 如果版本选择错误,会出现乱码的结果,请多多尝试

工具2.0 使用方法

  1. 运行工具,选择导出的连接文件,点击解密即可
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/yang2330648064/article/details/132791535