5 个版本
0.1.1 | 2023年12月19日 |
---|---|
0.1.0 | 2023年6月26日 |
1074 在 编码 中
43KB
457 行
BANANAPEEL — 一个滑稽的混淆系统
香蕉皮 是一种新颖的混淆算法,它接受文本,通常是某些加密算法的密文,并将其编码为一系列“块”,这些块被有意设计成与校验和相似。实用的是,这些块可以按任何顺序传输,因为每个块都有一个唯一的前缀,表示其在块集中的顺序。然而,新颖的是,这些前缀是从伪随机数生成器中派生出来的,该生成器的种子成为重新排列块所需的关键。
因此,Bananapeel不仅将数据混淆到几乎无法识别的程度,还使得在没有暴力破解的情况下,无法重建一定数量的块的数据。这包括破解所有可能的排列(随着块的数量以阶乘的方式增长),或者破解所有可能的密钥(理论上存在2^192
,尽管在实践中,暴力破解2^128
部分密钥就能提供足够的信息来完成统计分析攻击)。由于35! > 2^128
,因此,任何编码成超过35个块的数据都将需要攻击者破解所有可能的密钥。此外,Bananapeel具有独特的性质,由于其解码系统需要排序,如果尝试了错误的密钥,由于错误的随机数生成器种子,数据中的顺序前缀永远不会被找到,导致几乎所有错误的密钥都会进入无限循环。因此,暴力破解攻击者必须对每次解码设置时间限制。根据块的数量,在中等长度的消息中,这可以在消费级硬件上达到或超过一秒钟,即使将每个密钥尝试的时间缩短到一毫秒,如果按顺序进行,这仍然需要10^28
年。
当然,所有这些都假设攻击者无法简单地反转两个基本的编码过程,并尝试像拼图一样拼接块,这就是为什么强烈建议使用Bananapeel对实际加密算法的密文进行编码,而Bananapeel本身仅作为混淆工具,并便于按任何顺序传输编码块。此外,由于Bananapeel独特地需要密钥进行解码,在需要解密密钥的场合使用它,比在密钥传输不可行的场合简单得多。
使用方法
要通过CLI使用Bananapeel,您可以安装Rust实现,这为您提供了编码和解码能力。但是,如果您只需要解码,那么精简的Python或JavaScript实现可能更适合您的需求(分别适用于系统和网络应用程序)。
CLI
要安装,请运行
cargo install bananapeel
然后,您可以运行bananapeel encode <plaintext-file>
和bananapeel decode -k <key> <ciphertext-file>
。由于算法的特性,不支持提供自定义密钥,编码命令将打印base64密钥到stdout。
JS
位于bananapeel.min.js
的JavaScript实现公开了一个函数,bpDecode(key_str, partitions)
,它将字符串密钥作为第一个参数,将输出块数组(当然,可以以任何顺序)作为第二个参数。它将返回UTF-8格式的明文字符串。
此设计用于在网页浏览器或NodeJS中使用。
Python
位于bananapeel.min.py
的Python实现是一个独立的脚本,可以像这样调用
cat <ciphertext-file> | python bananapeel.min.py "<key>"
然后将解码后的明文写入标准输出。该功能设计用于与下载的脚本等类似的内容(例如:curl <some-script-url> | python bananapeel.min.py "<key>" | bash
)
参数
Bananapeel 算法有多个参数,这些参数有助于理解编码过程。
输出长度:每个输出块的字节长度,作为十六进制字符数。这可以使得每个块看起来像是某个算法的哈希值。对于相同大小的输入数据,此处值越小,通过增加块排列的可能性来提高安全性,尽管典型值是 64(SHA256 哈希的长度,以十六进制字符计)。
每个块的最小数据量:每个块中应填充的实际数据的十六进制字符的最小数量,剩余部分为噪声。这必须大于输出长度减去 8(前 8 个字符用于顺序前缀)。请注意,实际噪声量将随机生成,可能会产生噪声较少的块。此处值越大,输出块的数量就越少,因此需要破解的排列组合就越少,这会略微降低安全性。默认值是 32(噪声和数据之间的均等分割或更好)。
最大跳过概率:PRNG 中给定值被跳过的最大概率,以小于 1 的浮点数表示。例如,如果这是 0.75
,那么 PRNG 的顺序前缀中最多有 75% 将被跳过。此处值越大,顺序前缀之间的距离就越大,导致解码过程适度变慢。在解码过程中,将尝试每个前缀,如果找不到则忽略。因此,值为 0.75
意味着最多有 75% 的尝试前缀不会出现。如果攻击者尝试使用无效的密钥(例如,在暴力破解时),他们可能永远看不到足够的有效前缀(并且只有完全随机的情况下才会出现),因此必须在暴力破解中设置时间限制。如果此值足够高,典型的限制时间可能不足以使用正确密钥解码。简而言之,此参数的值越高,安全性就越高。默认值是 0.75
。
存储库内容
此存储库包含 Bananapeel 的完整 Rust 实现,其文档可在 此处 找到,以及一个仅解码器的 JavaScript 实现。通常,您会希望使用压缩版本,它可在 bananapeel.min.js
中找到,该版本公开了一个名为 bpDecode
的单个函数,它接受 base64 编码的 Bananapeel 密钥作为其第一个参数,以及作为其第二个参数的块数组,返回原始输入到 Bananapeel 的字符串消息。
通常,如果您可以使用 Rust 实现,则最好使用它,因为它将更快,并且可能错误更少(主要因为 Rust 具有合理的整数管理,而 JS 的 53 位精度则相当难以理解),然而 JS 实现是为了使用案例,例如 Cyst,该算法最初是为这些使用案例设计的。
此外,还有一个高度压缩和混淆的 Python 实现位于 bananapeel.min.py
,长度不到 800 个字符。这是设计用于与可以通过 stdin 读取的 shell 脚本一起使用的。
安全性
香蕉皮 是我在尝试混淆一个 Bash 脚本时产生的随机想法,并且从未接受过任何正式的安全审计!如果与强大的加密算法结合使用,香蕉皮 在我有限的认知中不应降低该算法的安全性,然而不建议在任何需要安全性的上下文中将该算法应用于明文,因为这几乎肯定会以眼泪收场。
许可证
请参阅LICENSE
。
依赖项
约 1.5-2.3MB
约 43K SLoC