daksh7011/Nyx
GitHub: daksh7011/Nyx
Nyx 是一款基于 Compose Multiplatform 的跨平台图像隐写应用,使用 AES-256-GCM 加密并将密文嵌入 PNG 像素的最低有效位中,让用户用密码加解密隐藏在图片里的文本信息。
Stars: 1 | Forks: 1

# Nyx
**你有想要分享的秘密吗?把它藏进一张图片里,并用密码锁起来。**
[](LICENSE) [](https://github.com/daksh7011/Nyx/actions/workflows/ci.yml)
## 概述
Nyx 将加密的文本信息隐藏在普通图片的像素中。
信息使用从你的密码派生出的密钥通过 AES-256-GCM 进行封装,
写入图像 RGB 通道的最低有效位中,并
导出为无损的 PNG 格式。对其他人来说,它只是一张图片;有了
密码,Nyx 就能准确还原原始信息。
Nyx 是一款 Compose Multiplatform 应用:只需一个 Kotlin 代码库即可运行在 Android、
桌面端 (Linux/macOS/Windows)、Web 端 (Kotlin/Wasm) 以及 iOS 上。
## 工作原理
```
message ──(AES-256-GCM)──> encrypted blob ──(LSB embed, 2 bits per R/G/B channel)──> stego PNG
key = PBKDF2-HMAC-SHA256(password, 600,000 iterations, random 16-byte salt)
```
1. **Encrypt** — 明文通过 AES-256-GCM 封装。每条信息都会获得一个
全新的随机 salt 和 nonce,因此加密相同的文本两次会生成
不同的数据块。GCM 是经过认证的:错误的密码或被篡改的图像
会彻底失效——你绝不会得到乱码输出。
2. **Embed** — 加密的数据块会被加上标记帧,并分散到每个像素的红色、绿色和蓝色通道的
两个最低有效位中。写入位置通过带密钥的置换进行打散,因此 payload 不会留下
任何聚集区域。对于单张图片来说过大的 payload 可以跨越多张图片。
3. **Export** — 结果始终为 PNG 格式(无损——这是让 payload
得以保留的必要条件)。解密则反转该流程:提取、认证、解密。
## 功能
- **加密向导** — 选择一张载体图像(各平台均支持文件选择器,
Android/iOS 支持相机拍照),输入信息和密码,即可获得一张保存到你的
vault 中并随时准备分享的隐写 PNG 图片。
- **Vault** — 以网格形式展示你的隐写图像,支持详情查看、分享/导出、
归档和删除。元数据存储在 SQLDelight 中;图像字节以 PNG
文件形式存储在磁盘上。
- **解密** — 打开 vault 中的图像或选择任何图像,输入密码,
即可显示并复制隐藏的信息。对于密码错误和未包含隐藏信息的情况,
会给出明确且截然不同的如实反馈。
- **主题** — 五种调色板(Midnight、Espresso、Nardo、Cream、Mist),支持
系统/浅色/深色模式覆盖,并在多次启动时保持设置。
- **设置** — 关于、开源许可证、擦除 vault、应用版本。
- **无广告、无账号、无网络** — Nyx 不会发起任何网络请求。
你的图像和秘密永远不会离开你的设备。
## 平台
| 平台 | Vault 持久化 | 相机捕获 | 备注 |
|---|---|---|---|
| Android 12+ (API 31) | 是 | 是 | 主要目标平台 |
| Desktop JVM (Linux / macOS / Windows) | 是 | 否 | Compose for Desktop |
| Web (Kotlin/Wasm) | 仅限会话 | 否 | 加密 / 解密 / 导出功能完全可用;vault 列表目前仅存储在内存中 |
| iOS (设备 + 模拟器) | 是 | 是 | 仅在 macOS 环境下构建 |
## 架构
```
flowchart TD
subgraph Entry["Entry apps"]
android[":androidApp"]
desktop[":desktopApp"]
web[":webApp"]
ios["client/iosApp (Xcode project, macOS-only)"]
end
subgraph ClientLayer["Client"]
clientMod[":client — initKoin, App(), NyxDb (SqlDelight) + VaultSource, iOS source impls"]
end
subgraph Features["Features — each split :feature:*:client:{api, basic}"]
feat["navigation · splash · theme · vault · encrypt · decrypt · settings"]
common[":feature:common:client:{api, koin}"]
end
subgraph Shared["Engines and shared"]
crypto[":crypto (AES-256-GCM, PBKDF2)"]
steg[":steganography (pure-Kotlin LSB codec)"]
data[":shared:data (results, source interfaces, events, clock, ids)"]
pres[":shared:presentation (BaseViewModel, ViewState/UiState)"]
design[":shared:design-library (Nx* + tokens) incl. :snapshot goldens"]
end
subgraph TestInfra["Test infra"]
ts[":shared:test-support"]
cts[":shared:compose-test-support"]
end
android --> clientMod
desktop --> clientMod
web --> clientMod
ios --> clientMod
clientMod --> Features
feat --> common
Features --> Shared
TestInfra -.-> ClientLayer
TestInfra -.-> Features
TestInfra -.-> Shared
```
- **功能模块** (`:feature:X:client:{api,basic}`):`api` 暴露
`Feature` 接口以及类型安全的 `@Serializable` 路由;`basic` 在隔离的 Koin 容器中实现
该接口。`basic` 模块从不依赖于另一个功能的
`basic`——它只能依赖于另一个功能的 `api` 以便访问其
路由(例如 vault → 加密/解密)。跨功能的运行时信号传递通过
`DomainEventBus` 进行。
- **Engines**:`:crypto` (cryptography-kotlin,AES-256-GCM + PBKDF2) 和
`:steganography` (基于 `PixelImage` 的纯 Kotlin LSB 编解码器) 不依赖于任何其他
项目模块,并通过用例被调用。
- **`:client`** 拥有全局 DI、SqlDelight 数据库 (`NyxDb`) 及其基于
SqlDelight 的 `VaultSource`,以及 iOS 平台源实现
(iOS 没有独立的应用模块)。Android、桌面端和 Web 端的实现
位于各自的入口应用模块中。
- **设计系统**:`Nx*` 原子组件包含主题 token,为
每种视觉状态提供预览,并在
`:shared:design-library:snapshot` 中进行 Paparazzi 黄金测试。
- `build-logic/` 中的 **约定插件** 保持了模块构建脚本的
声明式特性;`gradle/libs.versions.toml` 是唯一的版本来源。
## 构建
前置条件:JDK 21 和带有 API 37 的 Android SDK。iOS 另外需要
配备 Xcode 的 macOS。
```
./gradlew build # everything: assemble + tests + detekt
./gradlew :androidApp:assembleDebug # Android APK
./gradlew :androidApp:installDebug # install on a connected device
./gradlew :desktopApp:run # run the desktop app
./gradlew :webApp:wasmJsBrowserDevelopmentRun # dev server for the web app
./gradlew :shared:design-library:snapshot:verifyPaparazziDebug # design-system goldens
```
**Linux / Windows 注意事项:** iOS 目标会被自动跳过
(`kotlin.native.ignoreDisabledTargets=true`);其他所有内容均可在
本地构建和测试。iOS 编译和
`client/iosApp/` Xcode 项目会在 macOS 环境下进行验证。
## 安全模型(请务必阅读)
- **安全层在于密码学,而不是隐写术。** 信息
使用 AES-256-GCM 加密;密钥通过
PBKDF2-HMAC-SHA256 从你的密码派生而来,包含 60 万次迭代和一个随机的 16 字节 salt,并且每条信息都有一个
全新的随机 nonce。GCM 是一种认证加密——错误的
密码或被修改的图像都会被检测到并拒绝,绝不会悄无声息地被
解密成噪音。
- **LSB 隐写术是一个混淆层。** 编解码器通过带密钥的置换将嵌入的
比特分散到整个图像中,以防止 RS / 样本对隐写分析发现聚集区域——但请假设强大的对手仍然能够
检测出*某些东西*被隐藏了。然而没有你的密码,他们无法
读取它。
- **PNG 只能在无损通道中存活。** 会对图像进行重新压缩(通常压缩为 JPEG)的通讯应用和社交网络
会破坏 payload。请将隐写
图像作为文件分享,而不是作为内联照片发送。
- **你的密码决定了一切。** 无论迭代次数多少,弱密码都会被离线
破解。没有任何恢复机制:失去
密码,就失去了信息。
- **与重写前的 Nyx 彻底脱节。** 旧版(2026 年之前)的
Android 应用生成的图像使用的是已废弃的格式,无法被当前版本解密。
Nyx 是一个实验性的开源项目,基于
MIT 许可证发布,不提供任何形式的担保。它通过
[cryptography-kotlin](https://github.com/whyoleg/cryptography-kotlin) 构建于经过严格审查的加密原语之上,但它
尚未经过独立审计。请勿将其作为保护高风险秘密的
唯一手段。
## 邮件赞助软件
Nyx 是一款邮件赞助软件 (emailware)。如果你喜欢使用这款应用,或者它在任何方面帮助到了你,请发邮件给
[daksh@technowolf.in](mailto:daksh@technowolf.in) 告诉我——任何你想
说的内容都可以。如果能听到这个项目对某些人
有所帮助,我会真心感激。 :)
## 许可证
[MIT 许可证](LICENSE) — 版权所有 (c) 2020 TechnoWolf FOSS
标签:AES加密, Kotlin, 信息隐藏, 后台面板检测, 图像隐写, 密码学, 手动系统调用, 跨平台应用