首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【工具】Navicat 17 导出的 connections.ncx 文件密码解密

【工具】Navicat 17 导出的 connections.ncx 文件密码解密

作者头像
框架师
发布于 2025-06-06 04:21:29
发布于 2025-06-06 04:21:29
34000
代码可运行
举报
文章被收录于专栏:墨白的Java基地墨白的Java基地
运行总次数:0
代码可运行

前言

企业级开发中会有很多数据库链接信息,如果有遗漏可能就会导致忘记了数据库密码,那么使用 navicat 存储过数据库信息就可以查询到数据库密码,操作方式如下:参考博客 , 参考博文导出数据库链接信息,博文写的 php 代码已经无法执行,借助 grok 整了一个 Java 版本的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;

public class NavicatPassword {
    private final int version;
    private final byte[] aesKey = "libcckeylibcckey".getBytes(StandardCharsets.UTF_8);
    private final byte[] aesIv = "libcciv libcciv".getBytes(StandardCharsets.UTF_8);
	private final byte[] blowKey;
    private final byte[] blowIv;

    public NavicatPassword(int version) throws Exception {
        this.version = version;
		String blowString = "3DC5CA39";
		this.blowKey = sha1(blowString);
        this.blowIv = hexToBytes("d9c7c3c8870d64bd");
    }

    public String decrypt(String hexCipher) throws Exception {
        return switch (version) {
            case 11 -> decryptEleven(hexCipher);
            case 12 -> decryptTwelve(hexCipher);
            default -> throw new IllegalArgumentException("Unsupported version:" + version);
        };
    }
    private String decryptTwelve(String hexCipher) throws Exception {
        byte[] encrypted = hexToBytes(hexCipher);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(aesIv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return new String(decrypted, StandardCharsets.UTF_8);
    }
    private String decryptEleven(String hexCipher) throws Exception {
        byte[] data = hexToBytes(hexCipher);
        byte[] result = new byte[0];
        byte[] currentVector = Arrays.copyOf(blowIv, blowIv.length);
        int rounds = data.length / 8;
        int left = data.length % 8;

        for (int i = 0; i < rounds; i++) {
            byte[] block = Arrays.copyOfRange(data, i * 8, i * 8 + 8);
            byte[] decrypted = decryptBlowfish(block);
            byte[] xored = xorBytes(decrypted, currentVector);
            currentVector = xorBytes(currentVector, block);
            result = concat(result, xored);
        }

        if (left > 0) {
            byte[] padded = encryptBlowfish(currentVector);
            byte[] last = xorBytes(Arrays.copyOfRange(data, rounds * 8, data.length),
                    Arrays.copyOf(padded, left));
            result = concat(result, last);
        }

        return new String(result, StandardCharsets.UTF_8);
    }
    private byte[] encryptBlowfish(byte[] input) throws Exception {
        Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
        SecretKeySpec keySpec = new SecretKeySpec(blowKey, "Blowfish");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        return cipher.doFinal(input);
    }

    private byte[] decryptBlowfish(byte[] input) throws Exception {
        Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
        SecretKeySpec keySpec = new SecretKeySpec(blowKey, "Blowfish");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        return cipher.doFinal(input);
    }

    // Utility methods
    private byte[] xorBytes(byte[] a, byte[] b) {
        byte[] result = new byte[a.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = (byte) (a[i] ^ b[i]);
        }
        return result;
    }

    private byte[] sha1(String input) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        return md.digest(input.getBytes(StandardCharsets.UTF_8));
    }

    private static byte[] hexToBytes(String hex) {
        int len = hex.length();
        byte[] result = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            result[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return result;
    }

    private static byte[] concat(byte[] a, byte[] b) {
        byte[] result = Arrays.copyOf(a, a.length + b.length);
        System.arraycopy(b, 0, result, a.length, b.length);
        return result;
    }

    public static void main(String[] args) throws Exception {
        NavicatPassword np = new NavicatPassword(12);
        String encrypted = "connections.ncx 文件里面的 password";
        String decrypted = np.decrypt(encrypted);
        System.out.println("Decrypted:" + decrypted);
    }
}

代码复制到 idea 执行即可

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验