把 FinalShell 保存的主机、文件夹层级、密码和私钥,搬到 HaloShell。
在线使用:https://final2halo.com —— 也可以自己部署一份,见下方「自己部署」。
纯前端。 没有后端,没有上传,没有埋点。选目录、解密、生成迁移包这三件事全部发生在你自己的浏览器里,断网也能用。
页面的 CSP 里写死了 connect-src 'none',意思是浏览器禁止这个页面发起任何 fetch / XHR / WebSocket。「不会上传」因此不只是一句承诺,而是浏览器强制执行的规则——就算有人往依赖链里塞了偷传代码,它也发不出去。
-
打开 https://final2halo.com(或自己部署的地址)。
-
把 FinalShell 的数据目录拖进去,或点「选择文件夹」。
系统 目录 macOS ~/Library/FinalShellWindows FinalShell 安装目录 Linux ~/.finalshell拖
conn/子目录也能认,但那样读不到私钥和快捷命令——它们存在config.json里。 -
核对预览:左边是原样保留的文件夹层级,右边是该文件夹下的主机。
-
点「导出迁移包」,得到一个 JSON。
-
回到 HaloShell:先解锁保险箱(没解锁的话导入入口是灰的),再点主机列表顶部的「导入 / 导出」→「导入」,选择这个 JSON。
导入完请立刻删掉这个 JSON。 里面是明文密码和明文私钥——这是 HaloShell 明文迁移包的格式要求,不是本工具的选择。别发给别人,别放网盘。
| FinalShell | HaloShell |
|---|---|
conn/<id>/folder.json 的嵌套文件夹 |
hostGroups,父子层级原样保留 |
*_connect_config.json 的主机 |
hosts,含名称、地址、端口、用户名、备注、排序、最近连接时间 |
conection_type = 101(Windows 远程桌面) |
protocol: "rdp" |
密码认证(authentication_type = 1) |
auth.kind = "password",明文进保险箱 |
私钥认证(authentication_type = 2) |
auth.kind = "privateKey",私钥与口令进保险箱 |
config.json 的 secret_key_list |
保险箱里的 PEM 私钥 |
config.json 的 quick_commands |
quickCommands,命名为 分组名/命令名,HaloShell 据此还原分类 |
没保存密码、或私钥找不到的主机,会落成「本机密钥代理」认证,并在界面上逐条列出来,导入后手动补。
- 端口转发:FinalShell 的
port_forwarding_list。真实样本里全为空,没有可验证映射的数据,所以宁可不写没验证过的转换代码。遇到非空配置时工具会明确提示。 - 代理:同上,
proxy_id在样本里全是"0"。 - 终端外观、编码、字体等偏好:HaloShell 的迁移包不带这些。
backup/、deleted/目录:里面是历史版本和已删条目,会被主动跳过,免得把删掉的主机又导回来。
FinalShell 把密码用 DES 加密后 base64 存在 JSON 里。密钥不是固定的——它从密文头部 8 个字节,经由 java.util.Random 这个特定的 48 位线性同余发生器派生,再取 MD5 的前 8 字节作为 DES 密钥。
算法来自 FinalShell 自身,最早由 jas502n/FinalShellDecodePass 逆向公开。本项目用 TypeScript 重新实现了 java.util.Random、MD5 和 DES,没有任何运行时依赖(浏览器的 WebCrypto 不支持单 DES)。
测试用的是公开测试向量:
UU8hWV51DmVNgmX/pUd0LlaEo53VTa6s → beac3d85988e
npm install
npm run dev # 本地开发
npm test # 单元测试
npm run typecheck # 类型检查
npm run build # 产出 dist/这就是个静态站点,npm run build 出来的 dist/ 丢到任何地方都能跑。
Cloudflare Workers(官方站点用的就是这套):
npm run deploy # 等价于 npm run build && wrangler deploy仓库里的 wrangler.jsonc 配的是纯静态资源、不带 Worker 脚本——服务端压根不存在能碰到用户数据的代码路径。public/_headers 负责下发 CSP 和缓存策略。
官方站点用的是 Cloudflare 的 Workers Builds:在面板里连上这个仓库,构建命令填 npm run build、部署命令填 npx wrangler deploy,之后推 main 就自动发布。
Docker:
docker build -t final2halo .
docker run -p 8080:80 final2halo其他静态托管:直接传 dist/。部署在子路径下时构建要带上 base:
BASE_PATH=/final2halo/ npm run build- 工具不发起任何网络请求。你可以在浏览器开发者工具的「网络」面板里自己确认,或者干脆断网使用。
- 解密出来的密码默认在界面上是遮住的,需要逐个点「显示」。
- 导出的迁移包含明文凭据。仓库的
.gitignore已经拦掉finalshell-migration*.json,但请仍然手动删除。 - 这个工具只能解密你自己机器上的 FinalShell 配置。它不是破解工具——FinalShell 的这套加密对本地攻击者本来就不设防,密钥就藏在密文自己的头部里。
- 官方部署只有 https://final2halo.com 一个地址。这类工具天然适合被仿冒成钓鱼站,看到别的域名请当心。
完整的威胁模型、以及漏洞报告方式,见 SECURITY.md。
欢迎 Issue 和 PR。发 PR 前跑一遍 npm test 和 npm run typecheck。
提 Issue 时不要贴真实的主机地址、密码或私钥,构造一份假数据复现就够了。安全漏洞请走 SECURITY.md 里的私下渠道,别开公开 Issue。
如果你手上有本项目没有覆盖的 FinalShell 配置——比如用到了端口转发或代理的主机——欢迎脱敏后提供样本结构。这两块目前没迁移,正是因为缺少可验证的真实数据。
MIT
