atomskz/stegify
GitHub: atomskz/stegify
一个基于 LSB 隐写术的 CLI 工具与 C 库,用于在 PNG/BMP 图像中隐藏和提取数据。
Stars: 0 | Forks: 0
# stegify
通过命令行或 C 语言在图像中隐藏和恢复数据。
`stegify` 是一个小巧的 CLI 工具和 C 库,它使用 **LSB(最低有效位)隐写术** 将 payload 隐藏在 PNG 或
BMP 图像中:每个 payload 字节会分散到八个图像字节中,即每个字节的最低位存储一个 bit,因此图像看起来没有任何变化。payload 之前会有一个固定的头部(magic 字符 `STGF` + 版本字节 +
`uint32` 长度),因此对于未携带数据的图像,会报告为空,而不是返回乱码。版本 0.1.0。
## 两条命令搞定
```
stegify embed cover.png -m "Hello, stegify!" -o stego.png # hide it
stegify extract stego.png -p # read it back
```
`-p` 会将恢复的 payload 打印为十六进制 + ASCII 表格:
```
00000000 48 65 6c 6c 6f 2c 20 73 74 65 67 69 66 79 21 |Hello, stegify!|
```
## 构建
需要 **CMake ≥ 3.14**、**C99 编译器**,并在*首次*配置时具备网络访问权限(stb 通过 CMake 的 `FetchContent` 获取)。
```
# Linux / macOS
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build # binary: ./build/stegify
```
```
:: Windows (MSVC, multi-config)
cmake -S . -B build
cmake --build build --config Release :: binary: build\Release\stegify.exe
```
使用 `ctest --test-dir build` 运行测试。以下示例会调用 `stegify`;
请使用上述路径,或将该二进制文件添加到您的 `PATH` 中。
## 命令
图像路径是位置参数,必须排在**最前面**,位于所有选项之前。
| 命令 | 功能说明 | 示例 |
| --- | --- | --- |
| `embed` | 将字符串 (`-m`) 或文件 (`-f`) 隐藏在图像中,并保存至 `-o` | `stegify embed in.png -m "hi" -o out.png` |
| `extract` | 将 payload 恢复到 `-o` 和/或使用 `-p` 打印 | `stegify extract out.png -o data.bin` |
| `size` | 打印图像的最大 payload 容量 | `stegify size in.png` |
| `--help` / `--version` | 显示用法或版本号并退出 | `stegify --help` |
| 选项 | 含义 |
| --- | --- |
| `-m ` | 隐藏指定的字符串(仅限 `embed`;与 `-f` 互斥)。 |
| `-f ` | 隐藏指定文件的内容(仅限 `embed`;与 `-m` 互斥)。 |
| `-o ` | 输出路径 —— 对于 `embed` 是图像(必填),对于 `extract` 是数据文件(可选)。 |
| `-p` | 将 payload 打印为十六进制 + ASCII 表格。作用于 `extract` 以及 `embed -m`(不包括 `-f`)。 |
### 文件的往返隐藏与恢复
```
stegify size cover.png # capacity: 2039 bytes (0.002 MiB)
stegify embed cover.png -f secret.bin -o stego.png
stegify extract stego.png -o restored.bin
cmp -s secret.bin restored.bin && echo OK
```
## 图像格式
仅支持 **PNG** 和 **BMP** 格式。
- **输入**格式是通过文件的 *签名*(magic bytes)检测的,而非文件名
—— 即使将 JPEG 重命名为 `.png` 也会被拒绝。
- **输出**格式取决于输出路径的 *扩展名* —— 无论输入格式是什么,`-o out.bmp` 都会写入
BMP。
故意不支持 JPEG:因为它是是有损压缩的,重新编码会破坏
LSB payload。
## 容量
```
floor(width * height * channels / 8) - header_size
```
运行 `stegify size ` 以获取确切数值。
## 库 API
分为两层,均位于 `` 下;可编译的示例位于
[`core/examples/usage.c`](core/examples/usage.c)。
**基于路径的接口 — ``**(处理所有文件 I/O;从这里开始):
| 函数 | 用途 |
| --- | --- |
| `stegify_ops_embed` | 将内存中的 payload 嵌入图像并保存。 |
| `stegify_ops_embed_file` | 将 payload 文件嵌入图像并保存。 |
| `stegify_ops_extract` | 将 payload 提取到文件和/或调用者缓冲区。 |
| `stegify_ops_capacity` | 报告图像的最大 payload 容量。 |
**内存编解码器 — ``**(无文件 I/O):
| 函数 | 用途 |
| --- | --- |
| `stegify_image_load` | 从缓冲区解码图像。 |
| `stegify_image_export` | 将图像编码并通过写入回调输出。 |
| `stegify_image_free` | 释放已解码的像素缓冲区。 |
| `stegify_get_max_capacity` | 已加载图像的最大 payload 容量。 |
| `stegify_embed` / `stegify_extract` | 在像素的 LSB 中嵌入 / 提取数据。 |
| `stegify_error_string` | 返回状态码对应的易读文本。 |
每个函数都会返回一个 `stegify_status_t`:`STEGIFY_OK`、
`STEGIFY_ERR_INVALID_INPUT`、`STEGIFY_ERR_INVALID_IMAGE`、
`STEGIFY_ERR_UNSUPPORTED_FORMAT`、`STEGIFY_ERR_INSUFFICIENT_CAPACITY`、
`STEGIFY_ERR_MEMORY_ALLOC`、`STEGIFY_ERR_FILE_IO`、`STEGIFY_ERR_CORRUPTED_DATA`。
## 安全性与局限性
- **无保密性** —— payload 以明文形式存储,任何查看的人都能轻易
恢复它。
- 除了头部 magic 校验外,**没有完整性或身份验证**;无法检测到被修改的
容器(图像)。
- 使用标准的隐写分析**很容易被检测到**。
- **极其脆弱** —— 任何有损重编码、缩放或格式转换都会破坏
payload;只有在无损、未修改的 PNG/BMP 中才能幸存。
- 输出路径会被**直接覆盖且不进行确认**。
如果您需要保密性或防篡改能力,请在嵌入 payload **之前**
对其进行加密和身份验证。
## 许可证
MIT —— 详见 [`LICENSE`](LICENSE) 文件。使用了
[`stb`](https://github.com/nothings/stb)(`stb_image`、`stb_image_write`),
在构建时通过 CMake 的 `FetchContent` 获取。
标签:Bash脚本, C语言库, 信息隐藏, 图像处理, 子域名枚举工具, 客户端加密, 隐写术