elegasoft / cipher
维吉尼尔密码的无密钥版本
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0
- laravel/prompts: ^0.1.15|^1.0
Requires (Dev)
- brianium/paratest: ^7.0|^8.0
- laravel/pint: ^1.0|^2.0
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^2.33
- phpunit/phpunit: ^10.0|^11.0
README
这是一个多字母数字密码,非常适合混淆明文,无论是普通还是不太普通的观察者,但它不应该作为使用强加密处理敏感数据的替代方案。
安装
您可以通过composer安装此包
composer require elegasoft/cipher
基本用法
// It only encodes characters in its character base $cipher = new Base62Cipher(config('cipher.keys.base62')); $cipher->encipher('hide-this-string-1111'); // returns 39O8-RBeX-4ZyGD6-o8pR $cipher->decipher('39O8-RBeX-4ZyGD6-o8pR'); // returns hide-this-message // It can encipher symbols in its character base $cipher = new Base96Cipher(config('cipher.keys.base96')); $cipher->encipher('hide-this-string-1111'); // returns (3]QC+2}SsoHzRz14I<~L $cipher->decipher('(3]QC+2}SsoHzRz14I<~L'); // returns hide-this-message
使用填充来扩展最小输出长度
$cipher = new Base96Cipher(config('cipher.keys.base96')); // It can pad the enciphered text to a minimal output length of 6 $cipher->paddedEncipher(string: 1, minOutputLength: 6, paddingCharacter: 'a'); // returns q3sp14 $cipher->paddedDecipher(encipheredString: 'q3sp14', paddingCharacter: 'a'); // return 1
注意:使用不同的密钥将产生与这里看到的不同加密文本输出。
它是如何工作的?(简化示例)
密码使用替换字母表来用密钥字母表的替换字符替换明文字符。此密码可以为明文字符串中的每个字符使用不同的密钥字母表。
使用 Base62Cipher::encifer('Hello!')
和 3 个密钥,以下结果会发生
- 明文 "H" 是
Base62
字符集中的第 32 个字符,它将被替换为第一个密钥
中的第 32 个字符 - 明文 "e" 是
Base62
字符集中的第 5 个字符,它将被替换为第二个密钥
中的第 5 个字符 - 明文 "l" 是
Base62
字符集中的第 12 个字符,它将被替换为第三个密钥
中的第 12 个字符 - 明文 "l" 是
Base62
字符集中的第 12 个字符,它将被替换为第二个密钥
中的第 12 个字符 - 明文 "o" 是
Base62
字符集中的第 15 个字符,它将被替换为第三个密钥
中的第 15 个字符 - 明文 "!" 不会被替换,因为它不在
Base62
字符集中,但如果它是可替换的字符,替换将发生在第一个密钥
中
它真正是如何工作的?
如果你使用上面的简化示例,第一个字符将按提供的准确加密,然而,从 "e" 字符开始,并从这里继续。在将 "e" 替换为第 5 位置的字符之前,密钥将按顺序旋转,直到 "H" 字符位于 0 索引位置。然后选择第 5 位置的字符。密码将继续切换密钥流并旋转它们,直到前一个字符位于 0 索引位置之前,然后选择下一个字符,直到达到字符串的末尾。
这种行为通过很少的计算努力增加了解密的复杂性,因为以不同字符开始的字符串将产生截然不同的结果。
// For example $cipher = new Base62Cipher(config('cipher.keys.base62')); $cipher->encipher('bat'); // Outputs eaO $cipher->encipher('cat'); // Outputs koB $cipher->encipher('hat'); // Outputs 3A9 $cipher->encipher('mat'); // Outputs PX2
如果密钥不是根据前一个字符旋转,那么四个字符串的加密输出将具有相同的最后两个字符。
独特性和处理顺序输入
因为这只是一个密码,而不是哈希算法,每个输入都应产生一个单一输出。我已经运行了多达一百万个不同输入的多个模拟,并且没有发现重复。然而,如果发送连续输入,会出现明显的趋势。
例如
$cipher = new Base62Cipher(config('cipher.keys.base62')) $cipher->encipher('aaaaaaaa') // Outputs tW7vz1pT $cipher->encipher('aaaaaaab') // Outputs tW7vz1pu $cipher->encipher('aaaaaaac') // Outputs tW7vz1pn $cipher->encipher('aaaaaaad') // Outputs tW7vz1p7
如果你预计会有很多连续输入,我建议使用 reverseEncipher
和 reverseDecipher
来减少连续相似性。
例如
$cipher = new Base62Cipher(config('cipher.keys.base62')) $cipher->reverseEncipher('aaaaaaaa') // Outputs tW7vz1pT $cipher->reverseEncipher('aaaaaaab') // Outputs ea5H4Kt2 $cipher->reverseEncipher('aaaaaaac') // Outputs kouIgSfE $cipher->reverseEncipher('aaaaaaad') // Outputs r4m7jswy
显然,由于这种密码算法的特性,肯定会出现一些额外的模式,所以请用它来混淆信息,而不是用于加密。
冲突/限制
冲突是哈希算法的问题,因为它们以可变长度的字符串作为输入,并以固定长度的字符串作为输出。这个 Elegasoft\Cipher
没有固定的输出长度,也不对输入进行哈希处理。相反,它执行密码替换,所以把它想象成把从你熟悉的语言转换成你从未见过的语言,而且它并不像正常语言那样运行。当使用 Elegasoft\Cipher
时,输出长度等于输入长度。
解码/解密的可能性?
我不是密码学家,这还没有经过密码学家的审查,所以我无法计算破解密码的难度,但根据可用的信息,你不应该尝试暴力破解这个密码。
实际上,没有人能真正回答解密有多难的问题,因为我们还需要了解一些未知因素才能做出更明智的决定。
- 正在加密的字符串有多长?
- 你使用了多少个加密密钥来加密字符串?
- 你使用了哪种加密方法?
- 你的加密密钥有多随机?
为了增加解密的难度,请使用更长的字符串(即使需要填充),并增加随机性和加密密钥的数量。但最重要的是不要共享你的加密密钥。
在编写了这个密码算法之后,我试图找出它是哪种类型的密码。在我的有限研究中,我能找到的最近似的密码是一种多字母密码,它并不完全接近一次性密码,这取决于你如何共享编码内容,以及你是否保密地保留密钥。
如果你是密码学家,请随时给我留言,我很想了解更多。
这个解决什么用例问题?
我正在寻找一种缩短URL的方法,无需担心冲突,这应该是一个有趣的项目。在没有指导或研究的情况下,经过几天的破解,我发现我可能真的发明了自己的谜题机器。
测试
composer test
更新日志
请参阅 更新日志 了解最近更改的更多信息。
贡献
请参阅 贡献指南 了解详细信息。
安全
如果你发现任何安全相关的问题,请通过电子邮件 jason@elegasoft.com 而不是使用问题跟踪器。
致谢
许可证
MIT许可证(MIT)。请参阅 许可证文件 了解更多信息。
Laravel软件包模板
此软件包是使用 Laravel软件包模板 生成的。