Navicat究竟如何加密密码?how-does-navicat-encrypt-password项目v1版Blowfish自定义流水线逐行精讲

📅 2026/8/24 17:16:59
Navicat究竟如何加密密码?how-does-navicat-encrypt-password项目v1版Blowfish自定义流水线逐行精讲
Navicat究竟如何加密密码how-does-navicat-encrypt-password项目v1版Blowfish自定义流水线逐行精讲【免费下载链接】how-does-navicat-encrypt-passwordTransferred from https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password项目地址: https://gitcode.com/gh_mirrors/ho/how-does-navicat-encrypt-passwordNavicat 究竟如何加密密码how-does-navicat-encrypt-password 项目把答案完整讲透当你勾选Save Password后Navicat 会用Blowfish 算法 写死的固定密钥把数据库密码变成一串十六进制字符悄悄存进Windows 注册表。本项目不仅逆向讲清了这套 v1 加密流水线还提供了 Python3 / C / C# / Java / VB.NET 五种语言的解密工具一行命令即可还原明文密码 。一、先看现场注册表里的加密密码用 Navicat 新建连接并勾选Save Password后点 OK密码并不会以明文落盘而是被加密后写入注册表例如HKEY_CURRENT_USER\Software\PremiumSoft\Navicat\Servers\连接名。如上图所示Pwd值就是一串大写十六进制如E817D1F31641A06EC0B4016FA这正是 v1 版 Blowfish 加密流水线的产物。下面逐段拆解它的生成过程。二、第1步写死的密钥 3DC5CA39v1 算法的密钥并不是用户的任何输入而是 Navicat 内置的一串 8 字节常量const uint8_t DefaultKey[8] { 3,D,C,5,C,A,3,9 };接着对这串 ASCII 文本做SHA-1得到 20 字节160 位摘要直接作为 Blowfish 的密钥accel_SHA1(DefaultKey, sizeof(DefaultKey), KeyHash); accel_Blowfish_set_key(KeyHash.byte, sizeof(KeyHash), BlowfishKey);这段代码在 cpp/NavicatCrypto.hpp 的Navicat11Crypto构造函数中。SHA-1 的实现见 cpp/sha1.cBlowfish 实现见 cpp/blowfish.c。⚠️ 关键点所有用户的密钥完全相同。这意味着任何拿到密文的人都能解密——加密更多是防肉眼偷窥而非防攻击。三、第2步生成初始向量 IVBlowfish 每次只能加密 8 字节必须准备一个初始向量IV。Navicat 的做法很取巧把 8 个0xFF当作明文用上面的密钥做ECB 加密密文就是 IVuint8_t CV[8] { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; accel_Blowfish_encrypt(CV, BlowfishKey, BLOWFISH_BIG_ENDIAN);算出的固定 IV 为D9C7C3C8870D64BD。注意这里用 ECB 模式只是借它的单块加密能力本身不参与链式处理。四、第3步自定义加密流水线逐段精讲密码串按 8 字节切块送入一条类似 CFB 但规则被魔改的流水线对照 cpp/NavicatCrypto.hpp 中EncryptString的核心循环temp.qword blocks[i]; // ① 取一个8字节明文块 temp.qword ^ *reinterpret_castuint64_t*(CV); // ② 与当前CV异或 accel_Blowfish_encrypt(temp.byte, BlowfishKey, ...); // ③ Blowfish加密 *reinterpret_castuint64_t*(CV) ^ temp.qword; // ④ CV CV ⊕ 密文块步骤操作与标准 CFB 的区别①取明文块 P[i]相同②P[i] ⊕ CV相同③Blowfish 加密得 C[i]相同④CV CV ⊕ C[i]❗ 标准 CFB 是CV C[i]这里却是异或旧 CV第 ④ 步是整个算法最非标准的地方链式状态是累积异或而不是直接替换这让流水线的扩散行为与标准 CFB 完全不同也是解密时必须原样复刻的原因。五、第4步尾块的捷径最后一个不足 8 字节的块不走完整流程代码只有三行accel_Blowfish_encrypt(CV, BlowfishKey, ...); // 把CV加密一次 for (size_t i 0; i srclen % 8; i) CV[i] ^ blocks_full[i]; // 尾块明文直接异或输出即CV Blowfish(CV)输出 尾块明文 ⊕ CV 的前几字节。尾块不参与链式更新解密时同样处理即可。六、第5步拼接十六进制入注册表每块 8 字节密文转 16 个大写十六进制字符所有块首尾拼接最终写入注册表Pwd。这也解释了为什么注册表里的密文长度一定是 16 的倍数、或尾部短一截对应不足 8 字节的尾块。解密就是整个流水线的逆序见 cpp/NavicatCrypto.hpp 的DecryptString整块先 Blowfish 解密再与 CV 异或尾块则再次加密 CV 后异或还原。七、动手验证一行命令还原密码项目python3/目录提供了现成工具依赖pip install cryptography pywin32$ ./navicat-cipher.py enc -v1 This is a test 0EA71F51DD37BFB60CCBA219BE3A $ ./navicat-cipher.py dec -v1 0EA71F51DD37BFB60CCBA219BE3A This is a testpython3/navicat-cipher.pyv1/v2/v3 三版算法的加解密命令行其中NavicatCryptoV1类是本文流水线的参考实现python3/show-navicat.py一键列出注册表中所有 Navicat 连接并解密密码python3/ncx-dump.py解析导出的.ncx连接备份文件本地克隆仓库即可开始实验$ git clone https://gitcode.com/gh_mirrors/ho/how-does-navicat-encrypt-password八、多语言源码地图v1 流水线的等价实现分散在五个语言目录方便你按熟悉的技术栈对照阅读语言文件说明Ccpp/NavicatCrypto.hpp —— v1/v2 算法完整类实现Python3python3/navicat-cipher.py —— 三版算法命令行工具C#csharp/NavicatCrypto.cs —— .NET 版加解密类Javajava/NavicatCrypto/Navicat11Cipher.java —— 使用Blowfish/ECB/NoPadding的 JCE 实现VB.NETvb.net/NavicatEncrypt.vb —— 基于 CryptSharp 的移植版九、安全启示回顾 v1 版的全链路固定密钥 固定 IV 无随机数结果是同一密码在任何机器上密文都相同确定性加密且密钥就躺在公开源码里。因此这套加密只能防止旁人翻注册表时一眼看到明文绝不能视为真正的安全边界——如果你的密码在注册表里就要默认同机同权用户随时可读。读完本文你已经掌握了Navicat v1 密码加密的 5 个环节固定密钥 → SHA-1 派生 → ECB 生成 IV → 魔改 CFB 流水线 → 尾块捷径并能用项目工具亲手解密验证。想继续深入可对照 doc/how-does-navicat-encrypt-password.md 阅读原文并尝试实现 v2 版AES128/CBC/PKCS7Padding的差异部分 【免费下载链接】how-does-navicat-encrypt-passwordTransferred from https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password项目地址: https://gitcode.com/gh_mirrors/ho/how-does-navicat-encrypt-password创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考