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语言库, 信息隐藏, 图像处理, 子域名枚举工具, 客户端加密, 隐写术